Vaults
Encrypted per-tenant document stores that AI agents read via scoped tokens.
Vaults are encrypted document stores. Each vault holds documents encrypted at the application layer (AES-256-GCM envelope encryption) before they touch object storage — only ciphertext is written to R2, never plaintext. Decryption happens server-side on read, gated by scope and organization. Agents access a vault with a short-lived scoped token and never hold an encryption key.
See Encrypted Vaults for the design and threat model.
Create Vault
POST /v1/vaultsPermission: Master API key only.
{
"name": "client-contracts",
"description": "Confidential client documents"
}| Field | Required | Description |
|---|---|---|
name | Yes | Vault name (1–200 chars) |
description | No | Optional description (max 500 chars) |
On creation, Coregit generates a per-vault data encryption key (DEK), wraps it with the platform key encryption key (KEK), and stores only the wrapped DEK.
Response 201
{
"id": "es4x64dAJancMz6mEIX1N",
"name": "client-contracts",
"description": "Confidential client documents"
}List Vaults
GET /v1/vaultsReturns vaults the credential can read (a scoped token sees only its vaults: scopes).
{
"vaults": [
{ "id": "es4x64dAJancMz6mEIX1N", "name": "client-contracts", "description": null, "createdAt": "2026-01-01T00:00:00Z" }
]
}Delete Vault
DELETE /v1/vaults/:vaultIdPermission: write on the vault (or master key). Deletes the vault, all its documents
(DB rows), and their ciphertext objects in storage.
{ "deleted": true }Upload Document
POST /v1/vaults/:vaultId/documentsPermission: write on the vault (or master key).
The raw request body is the document bytes (any content type). The document name is passed
via the x-document-name header or the ?name= query parameter.
curl -X POST "https://api.coregit.dev/v1/vaults/$VAULT_ID/documents" \
-H "x-api-key: $API_KEY" \
-H "x-document-name: contract-2026.pdf" \
--data-binary @contract-2026.pdfThe body is encrypted with the vault DEK before being written to storage. Maximum document size is governed by the 25 MB request-body limit.
Response 201
{
"id": "dsnyv5fyEVOh22enSCRrh",
"vault_id": "es4x64dAJancMz6mEIX1N",
"name": "contract-2026.pdf",
"size_bytes": 84213,
"content_sha256": "20129070170f7f07..."
}List Documents
GET /v1/vaults/:vaultId/documentsPermission: read on the vault. Returns document metadata only (never content).
{
"documents": [
{ "id": "dsnyv5fyEVOh22enSCRrh", "name": "contract-2026.pdf", "sizeBytes": 84213, "contentSha256": "2012...", "createdAt": "2026-01-01T00:00:00Z" }
]
}Read Document
GET /v1/vaults/:vaultId/documents/:docIdPermission: read on the vault. Coregit fetches the ciphertext, decrypts it server-side,
and returns the plaintext bytes.
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="contract-2026.pdf"
X-Document-Name: contract-2026.pdfThis endpoint is the decrypt broker for agents: an agent presents a vaults:<id> read token,
receives the document, and never sees the DEK or KEK.
Delete Document
DELETE /v1/vaults/:vaultId/documents/:docIdPermission: write on the vault. Removes the DB row and the ciphertext object.
{ "deleted": true }Scopes
Vault access is granted via scoped tokens:
{
"vaults:es4x64dAJancMz6mEIX1N": ["read"],
"vaults:*": ["read", "write"]
}| Pattern | Meaning |
|---|---|
vaults:<id> | A single vault |
vaults:* | All vaults in the organization |
Permissions: read (list/read documents) and write (upload/delete documents, delete vault).
Creating a vault always requires a master key.
Agent access pattern
// Orchestrator (holds the master key) mints a short-lived, read-only vault token:
const { data } = await git.tokens.create({
name: "agent-task-123",
scopes: { "vaults:es4x64dAJancMz6mEIX1N": ["read"] },
expires_in: 3600, // 1 hour (minimum TTL) — revoke on task detach for tighter bounds
});
// Inject data.token into the sandbox as an env var. The agent reads documents
// with it and never holds an encryption key. Revoke when the task ends.