Vault
Store, govern, and resolve secret material — API keys, tokens, passwords, and keys — without ever exposing the secret to the principal that uses it. A namespace is a federated zone; a credential is a governed leaf encrypted at rest. No public endpoint ever returns a secret value: secrets are decrypted only at the internal, server-to-server resolve endpoint, only for exportable credentials, and every resolve is authorized against the acting principal and audited.
/api/v1/vaultAutomation triggers: view every Vault event, payload field, and predicate.
Namespaces
CRUD on namespaces — the federated zone that contains credentials. Creating a namespace mints the IAM zone and grants the creator the full sub-namespace bundle (which already covers creating credentials inside it). All public routes require a JWT and the X-Company-Id header.
/api/v1/vault/namespacesCreate Namespace
Create a namespace (mints the federated zone). The creator automatically receives vault:namespaces:* and vault:permissions:namespaces:manage on the new namespace path.
Bearer token required. Header: X-Company-Id. Permission: vault:namespaces:create (granted on org/{company_id}).
Request Body
| Name | Type | Description |
|---|---|---|
name* | string | Display name (1–200 chars). Unique within the company. |
slug | string | URL-safe id (≤ 64 chars), unique within the company. Derived from name when omitted. |
description | string | Optional free-text description |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Namespace ID |
company_id* | string (UUID) | Owning organisation |
name* | string | Display name |
slug* | string | URL-safe id |
description* | string | null | Description, or null |
allowed_consumer_services* | string[] | null | Optional consumer allow-list (Phase 2). null = open to any eligible principal. |
created_by* | string (UUID) | null | Principal that created the namespace, or null |
created_at* | string (ISO 8601) | Creation time |
updated_at* | string (ISO 8601) | Last update time |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Integrations",
"slug": "production-integrations",
"description": "Third-party API credentials for production."
}'Response
201 Created{
"id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"name": "Production Integrations",
"slug": "production-integrations",
"description": "Third-party API credentials for production.",
"allowed_consumer_services": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:30:00Z",
"updated_at": "2026-04-14T10:30:00Z"
}/api/v1/vault/namespacesList Namespaces
List namespaces for the company. Results are filtered to the namespaces the caller can view (vault:namespaces:view on the org or on a specific namespace path).
Bearer token required. Header: X-Company-Id. Filtered by vault:namespaces:view.
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | Namespace[] | Visible namespaces, newest first |
curl https://platform.ergondata.ai/api/v1/vault/namespaces \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"name": "Production Integrations",
"slug": "production-integrations",
"description": "Third-party API credentials for production.",
"allowed_consumer_services": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:30:00Z",
"updated_at": "2026-04-14T10:30:00Z"
}
]/api/v1/vault/namespaces/{namespace_id}Get Namespace
Retrieve a single namespace by ID.
Bearer token required. Header: X-Company-Id. Permission: vault:namespaces:view (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Namespace ID |
company_id* | string (UUID) | Owning organisation |
name* | string | Display name |
slug* | string | URL-safe id |
description* | string | null | Description, or null |
allowed_consumer_services* | string[] | null | Consumer allow-list (Phase 2), or null = open |
created_by* | string (UUID) | null | Creator principal, or null |
created_at* | string (ISO 8601) | Creation time |
updated_at* | string (ISO 8601) | Last update time |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK{
"id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"name": "Production Integrations",
"slug": "production-integrations",
"description": "Third-party API credentials for production.",
"allowed_consumer_services": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:30:00Z",
"updated_at": "2026-04-14T10:30:00Z"
}/api/v1/vault/namespaces/{namespace_id}Update Namespace
Update a namespace's name, description, or optional consumer allow-list. Only the supplied fields change.
Bearer token required. Header: X-Company-Id. Permission: vault:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Request Body
| Name | Type | Description |
|---|---|---|
name | string | New display name (1–200 chars) |
description | string | New description |
allowed_consumer_services | string[] | Optional consumer allow-list (Phase 2). Restricts which services/principal-types may become eligible here; omit or null = open. |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Namespace ID |
company_id* | string (UUID) | Owning organisation |
name* | string | Display name |
slug* | string | URL-safe id |
description* | string | null | Description, or null |
allowed_consumer_services* | string[] | null | Consumer allow-list (Phase 2), or null = open |
created_by* | string (UUID) | null | Creator principal, or null |
created_at* | string (ISO 8601) | Creation time |
updated_at* | string (ISO 8601) | Last update time |
curl -X PATCH https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"description": "Production-only third-party credentials."
}'Response
200 OK{
"id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"name": "Production Integrations",
"slug": "production-integrations",
"description": "Production-only third-party credentials.",
"allowed_consumer_services": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:30:00Z",
"updated_at": "2026-04-14T11:02:11Z"
}/api/v1/vault/namespaces/{namespace_id}Delete Namespace
Delete a namespace. Cascades to all credentials (and their versions) inside it, and soft-deletes the IAM resource.
Bearer token required. Header: X-Company-Id. Permission: vault:namespaces:delete (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
curl -X DELETE https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
204 No ContentCredentials
CRUD on credentials — the governed leaf — inside a namespace. A credential carries a type, a source (supplied or generated), an exportable flag, non-secret config, and (for keypairs) public_material. The secret material is encrypted at rest the moment it is written and lives only as ciphertext. No endpoint in this section ever returns a secret value — not on create, not on read. The value is decrypted only by trusted services through Vault's private internal contract, and only for exportable credentials. Today only source=supplied is accepted; generated material is Preview and returns 501.
/api/v1/vault/namespaces/{namespace_id}/credentialsCreate Credential
Create a credential inside a namespace. The plaintext material is sealed (envelope-encrypted) immediately and never persisted, logged, or echoed — the response is metadata only. Set exportable=false to make a key that can never be resolved, only operated on (Preview). source=generated is Preview and returns 501; create with source=supplied and provide material.
Bearer token required. Header: X-Company-Id. Permission: vault:namespaces:credentials:create (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Parent namespace ID |
Request Body
| Name | Type | Description |
|---|---|---|
name* | string | Display name (1–200 chars). Unique within the namespace. |
slug | string | Reference key (≤ 64 chars), unique within the namespace. Derived from name when omitted. |
type* | string | Credential type. Supplied types: api_key, bearer_token, basic_auth, oauth2_client_credentials, secret_value, config. Generated types (Preview): random_bytes, password, aes_key, hmac_key, rsa_keypair, ec_keypair, ed25519_keypair, ssh_keypair. |
source | string | How the material came to exist: supplied (you paste it) or generated (Vault generates it — Preview, returns 501).Default: supplied |
exportable | boolean | When true, the value can be resolved via vault:credentials:use. When false, the secret never leaves Vault and can only be operated on (Preview).Default: true |
config | object | Non-secret per-type config, e.g. {placement, name} for api_key, {username} for basic_auth, {client_id, token_url, scopes} for oauth2_client_credentials. Never holds the secret.Default: {} |
material* | string | The secret value (plaintext). Required for supplied credentials. Sealed immediately on write; never stored in the clear or returned. |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Credential ID |
company_id* | string (UUID) | Owning organisation |
namespace_id* | string (UUID) | Parent namespace |
name* | string | Display name |
slug* | string | Reference key |
type* | string | Credential type |
source* | string | supplied or generated |
exportable* | boolean | Whether the value can be resolved |
config* | object | Non-secret per-type config |
public_material* | string | null | Non-secret public half of a keypair (public key / certificate), or null. Never the secret. |
last_rotated_at* | string (ISO 8601) | null | When the material was last rotated, or null |
created_by* | string (UUID) | null | Creator principal, or null |
created_at* | string (ISO 8601) | Creation time |
updated_at* | string (ISO 8601) | Last update time |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/credentials \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"name": "Stripe API Key",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" },
"material": "sk_live_51HxxxxxxxxxxxxYOURKEY"
}'Response
201 Created{
"id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"namespace_id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"name": "Stripe API Key",
"slug": "stripe-api-key",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" },
"public_material": null,
"last_rotated_at": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:35:00Z",
"updated_at": "2026-04-14T10:35:00Z"
}/api/v1/vault/namespaces/{namespace_id}/credentialsList Credentials
List credentials in a namespace (metadata only). Results are filtered to the credentials the caller can view. The secret value is never included.
Bearer token required. Header: X-Company-Id. Filtered by vault:credentials:view.
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Parent namespace ID |
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | Credential[] | Visible credentials (metadata only), newest first |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/credentials \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"namespace_id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"name": "Stripe API Key",
"slug": "stripe-api-key",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" },
"public_material": null,
"last_rotated_at": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:35:00Z",
"updated_at": "2026-04-14T10:35:00Z"
}
]/api/v1/vault/credentials/{credential_id}Get Credential
Retrieve a credential's metadata — type, config, and public_material (for keypairs). This endpoint never returns the secret value.
Bearer token required. Header: X-Company-Id. Permission: vault:credentials:view (on the credential or its namespace).
Path Parameters
| Name | Type | Description |
|---|---|---|
credential_id* | string (UUID) | Credential ID |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Credential ID |
company_id* | string (UUID) | Owning organisation |
namespace_id* | string (UUID) | Parent namespace |
name* | string | Display name |
slug* | string | Reference key |
type* | string | Credential type |
source* | string | supplied or generated |
exportable* | boolean | Whether the value can be resolved |
config* | object | Non-secret per-type config |
public_material* | string | null | Public half for keypairs, or null. Never the secret. |
last_rotated_at* | string (ISO 8601) | null | When the material was last rotated, or null |
created_by* | string (UUID) | null | Creator principal, or null |
created_at* | string (ISO 8601) | Creation time |
updated_at* | string (ISO 8601) | Last update time |
curl https://platform.ergondata.ai/api/v1/vault/credentials/{credential_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK{
"id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"namespace_id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"name": "Stripe API Key",
"slug": "stripe-api-key",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" },
"public_material": null,
"last_rotated_at": null,
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:35:00Z",
"updated_at": "2026-04-14T10:35:00Z"
}/api/v1/vault/credentials/{credential_id}Update Credential
Update a credential's metadata or replace its secret material. Supplying material re-seals the value (envelope-encrypted) and stamps last_rotated_at; the plaintext is never persisted or returned. The response is metadata only.
Bearer token required. Header: X-Company-Id. Permission: vault:credentials:manage (on the credential or its namespace).
Path Parameters
| Name | Type | Description |
|---|---|---|
credential_id* | string (UUID) | Credential ID |
Request Body
| Name | Type | Description |
|---|---|---|
name | string | New display name (1–200 chars) |
config | object | Replacement non-secret per-type config |
exportable | boolean | Toggle whether the value can be resolved |
material | string | New secret value (plaintext). When provided, the credential is re-sealed and last_rotated_at is updated. Never stored in the clear or returned. |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string (UUID) | Credential ID |
namespace_id* | string (UUID) | Parent namespace |
name* | string | Display name |
type* | string | Credential type |
exportable* | boolean | Whether the value can be resolved |
config* | object | Non-secret per-type config |
public_material* | string | null | Public half for keypairs, or null |
last_rotated_at* | string (ISO 8601) | null | Updated when material is replaced |
updated_at* | string (ISO 8601) | Last update time |
curl -X PATCH https://platform.ergondata.ai/api/v1/vault/credentials/{credential_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"material": "sk_live_51HxxxxxxxxxxxxROTATED"
}'Response
200 OK{
"id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"company_id": "c0ffee00-cafe-babe-dead-beefcafebabe",
"namespace_id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"name": "Stripe API Key",
"slug": "stripe-api-key",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" },
"public_material": null,
"last_rotated_at": "2026-04-14T12:00:00Z",
"created_by": "u9000000-0000-4000-8000-000000000001",
"created_at": "2026-04-14T10:35:00Z",
"updated_at": "2026-04-14T12:00:00Z"
}/api/v1/vault/credentials/{credential_id}Delete Credential
Delete a credential and its sealed material, and soft-delete the IAM resource.
Bearer token required. Header: X-Company-Id. Permission: vault:credentials:delete (on the credential or its namespace).
Path Parameters
| Name | Type | Description |
|---|---|---|
credential_id* | string (UUID) | Credential ID |
curl -X DELETE https://platform.ergondata.ai/api/v1/vault/credentials/{credential_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
204 No ContentAccess Audit
Read the audit trail. Every resolve attempt — allow or deny — writes a credential_accesses row, and every namespace/credential mutation writes an activity log. Neither ever exposes a secret value.
/api/v1/vault/credentials/{credential_id}/accessesList Credential Accesses
Who resolved this credential, when, and with what outcome (allow or deny). One row per resolve attempt; the value is never stored or returned.
Bearer token required. Header: X-Company-Id. Permission: vault:credentials:view (on the credential or its namespace).
Path Parameters
| Name | Type | Description |
|---|---|---|
credential_id* | string (UUID) | Credential ID |
Query Parameters
| Name | Type | Description |
|---|---|---|
limit | integer | Results to return (1–500)Default: 100 |
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | AccessEntry[] | Access attempts, newest first |
curl "https://platform.ergondata.ai/api/v1/vault/credentials/{credential_id}/accesses?limit=50" \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"id": "ac1d0001-0000-4000-8000-000000000001",
"credential_id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"acting_principal_id": "cc110000-0000-4000-8000-000000000009",
"acting_principal_type": "service",
"via_service": "compute",
"action": "use",
"outcome": "allow",
"deny_reason": null,
"accessed_at": "2026-04-14T11:20:05Z"
},
{
"id": "ac1d0002-0000-4000-8000-000000000002",
"credential_id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"acting_principal_id": "a9ent000-0000-4000-8000-000000000003",
"acting_principal_type": "agent",
"via_service": "compute",
"action": "use",
"outcome": "deny",
"deny_reason": "use_denied",
"accessed_at": "2026-04-14T11:18:42Z"
}
]/api/v1/vault/activityList Activity
Org-scoped namespace/credential mutation log (created/updated/deleted, resolves). Diffs carry type, non-secret config, and metadata only — never secret material.
Bearer token required. Header: X-Company-Id. Permission: vault:activity:view (granted on org/{company_id}).
Query Parameters
| Name | Type | Description |
|---|---|---|
limit | integer | Results to return (1–500)Default: 100 |
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | ActivityEntry[] | Activity log entries, newest first |
curl "https://platform.ergondata.ai/api/v1/vault/activity?limit=50" \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"id": "10900001-0000-4000-8000-000000000001",
"event_type": "vault.credential.created",
"actor_id": "u9000000-0000-4000-8000-000000000001",
"actor_type": "member",
"namespace_id": "9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"credential_id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"payload": {
"credential_id": "3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"type": "api_key",
"source": "supplied",
"exportable": true,
"config": { "placement": "header", "name": "Authorization" }
},
"created_at": "2026-04-14T10:35:00Z"
}
]Access & Connections
Each namespace exposes the platform's standard per-zone access + connection surface under /namespaces/{namespace_id}/access/*. It is the same connect-then-grant protocol used across Ergon: view/create/revoke IAM grants, run the approver inbox for consumer connection requests, and list active inbound connections. Every endpoint here is gated by vault:permissions:namespaces:manage on the namespace, and all grant/connection logic is delegated to IAM — Vault stores no grants of its own.
/api/v1/vault/namespaces/access/grants/batchCreate Namespace Access Grants Batch
Create grants across namespace roots in one ordered, partial-success operation. Group a subject with resources and permission UUIDs; operations expand resources first and permission IDs second, to at most 200 grants total. Invalid or unauthorized items fail independently while valid items continue, and partial success returns 200. Whole-request retries are idempotent because existing natural grant tuples return already_exists. A side_effect_error means post-write reconciliation failed but the returned grant exists; retry that item or the whole request to reconcile it. ToolDef slug: vault.namespace_access.create_grants_batch.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage on every target namespace root.
Request Body
| Name | Type | Description |
|---|---|---|
operations* | array | 1–200 grouped operations; resources × permission_ids across all operations must expand to at most 200 grants |
Response Fields
| Name | Type | Description |
|---|---|---|
results* | array | One result per expanded grant, ordered by operation, then resource, then permission |
summary* | object | Outcome counts |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces/access/grants/batch \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{"operations":[{"client_ref":"consumers","principal_type":"workflow","principal_id":"{principal_id}","resources":["org/{company_id}/namespace/{namespace_id}/credential/{credential_id}"],"permission_ids":["{permission_id}"],"effect":"allow"}]}'Response
200 OK{
"results": [{
"index": 0,
"client_ref": "consumers",
"status": "created",
"principal_type": "workflow",
"principal_id": "{principal_id}",
"permission_id": "{permission_id}",
"resource": "org/{company_id}/namespace/{namespace_id}/credential/{credential_id}",
"effect": "allow",
"grant": {"id": "{grant_id}", "permission_id": "{permission_id}", "name": "vault:credentials:use", "resource": "org/{company_id}/namespace/{namespace_id}/credential/{credential_id}", "effect": "allow", "is_system": false, "granted_at": "2026-07-15T16:30:00Z"},
"error_status": null,
"error_detail": null,
"side_effect_error_status": null,
"side_effect_error_detail": null
}],
"summary": {"created": 1, "already_exists": 0, "failed": 0}
}/api/v1/vault/namespaces/{namespace_id}/access/grantsList Grants
List the IAM grants scoped to this namespace (and its credentials), paginated.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Query Parameters
| Name | Type | Description |
|---|---|---|
page | integer | Page number (≥ 1)Default: 1 |
limit | integer | Page size (1–500)Default: 100 |
Response Fields
| Name | Type | Description |
|---|---|---|
items* | GrantEntry[] | Grants on this namespace |
total* | integer | Total grants |
page* | integer | Page returned |
limit* | integer | Page size used |
curl "https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/grants?limit=50" \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK{
"items": [
{
"id": "9ra0t000-0000-4000-8000-000000000001",
"principal_type": "service",
"principal_id": "cc110000-0000-4000-8000-000000000009",
"principal_label": "Billing Sync Collection",
"permission_id": "perm_vault_credentials_use",
"permission_name": "vault:credentials:use",
"resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/namespace/9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90/credential/3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"effect": "allow",
"granted_at": "2026-04-14T11:00:00Z"
}
],
"total": 1,
"page": 1,
"limit": 50
}/api/v1/vault/namespaces/{namespace_id}/access/grantsCreate Grant
Grant a permission to a principal, scoped to this namespace or one of its credentials. Only namespace-grantable Vault permissions are accepted (e.g. vault:credentials:use, vault:credentials:view); the resource must be scoped under the namespace.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Request Body
| Name | Type | Description |
|---|---|---|
principal_type* | string | member, api_key, agent, role, team, automation, or workflow |
principal_id* | string | ID of the principal receiving the grant |
permission_id* | string | Permission to grant (must be grantable from a namespace) |
resource | string | Resource path to scope the grant to. Defaults to the namespace path; must be scoped under it (e.g. a specific credential). |
effect | string | allow or denyDefault: allow |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string | New grant ID |
permission_id* | string | Permission granted |
name* | string | Permission name |
resource* | string | Scoped resource |
effect* | string | allow or deny |
is_system* | boolean | Whether this is a system grant |
granted_at* | string (ISO 8601) | When the grant was created |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/grants \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"principal_type": "service",
"principal_id": "{principal_id}",
"permission_id": "{permission_id}",
"resource": "org/{company_id}/namespace/{namespace_id}/credential/{credential_id}",
"effect": "allow"
}'Response
201 Created{
"id": "9ra0t000-0000-4000-8000-000000000001",
"permission_id": "perm_vault_credentials_use",
"name": "vault:credentials:use",
"resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/namespace/9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90/credential/3a7d9e10-2b4c-4d6e-9f01-2a3b4c5d6e7f",
"effect": "allow",
"is_system": false,
"granted_at": "2026-04-14T11:00:00Z"
}/api/v1/vault/namespaces/{namespace_id}/access/grants/{grant_id}Revoke Grant
Revoke a previously created grant on this namespace.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
grant_id* | string | Grant ID to revoke |
curl -X DELETE https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/grants/{grant_id} \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
204 No Content/api/v1/vault/namespaces/{namespace_id}/access/connection-requestsList Connection Requests
The approver inbox: connection requests raised by consumers that want to use this namespace. Filter by status (defaults to pending).
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Query Parameters
| Name | Type | Description |
|---|---|---|
status | string | Filter by status: pending, approved, rejectedDefault: pending |
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | ConnectionRequestEntry[] | Connection requests targeting this namespace |
curl "https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/connection-requests?status=pending" \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"id": "c0nr0001-0000-4000-8000-000000000001",
"principal_id": "cc110000-0000-4000-8000-000000000009",
"principal_label": "Billing Sync Collection",
"direction": "inbound",
"target_service": "vault",
"target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/namespace/9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"requested_by": "u9000000-0000-4000-8000-000000000002",
"requested_permissions": ["vault:credentials:use"],
"message": "Need to read the Stripe key for the billing sync.",
"status": "pending",
"connection_id": null,
"decided_by": null,
"decided_at": null,
"created_at": "2026-04-14T10:55:00Z"
}
]/api/v1/vault/namespaces/{namespace_id}/access/connection-requests/{request_id}/approveApprove Connection Request
Approve a consumer's connection request. Optionally narrow the granted permissions (each must be grantable from a namespace) and set a connection label. This connects the principal and, when grant is true, issues the requested use grant.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
request_id* | string | Connection request ID |
Request Body
| Name | Type | Description |
|---|---|---|
permissions | string[] | Override the permissions to grant. Defaults to the request's requested_permissions. Each must be grantable from a namespace. |
grant | boolean | Whether to issue the grant on approvalDefault: true |
label | string | Optional label for the resulting connection |
Response Fields
| Name | Type | Description |
|---|---|---|
id* | string | Request ID |
status* | string | approved |
connection_id | string | null | ID of the connection created on approval |
decided_by | string | null | Approver principal |
decided_at | string (ISO 8601) | null | When it was approved |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/connection-requests/{request_id}/approve \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" \
-d '{
"permissions": ["vault:credentials:use"],
"grant": true,
"label": "Billing Sync"
}'Response
200 OK{
"id": "c0nr0001-0000-4000-8000-000000000001",
"principal_id": "cc110000-0000-4000-8000-000000000009",
"principal_label": "Billing Sync Collection",
"direction": "inbound",
"target_service": "vault",
"target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/namespace/9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"requested_permissions": ["vault:credentials:use"],
"message": "Need to read the Stripe key for the billing sync.",
"status": "approved",
"connection_id": "c0nn0001-0000-4000-8000-000000000007",
"decided_by": "u9000000-0000-4000-8000-000000000001",
"decided_at": "2026-04-14T11:00:00Z",
"created_at": "2026-04-14T10:55:00Z"
}/api/v1/vault/namespaces/{namespace_id}/access/connectionsList Connections
List the active inbound connections to this namespace — the principals that have been connected and granted access.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
Response Fields
| Name | Type | Description |
|---|---|---|
[]* | InboundConnectionEntry[] | Active inbound connections to this namespace |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/connections \
-H "Authorization: Bearer {token}" \
-H "X-Company-Id: {company_id}"Response
200 OK[
{
"connection_id": "c0nn0001-0000-4000-8000-000000000007",
"principal_id": "cc110000-0000-4000-8000-000000000009",
"principal_label": "Billing Sync Collection",
"target_service": "vault",
"target_resource": "org/c0ffee00-cafe-babe-dead-beefcafebabe/namespace/9b1f8c2e-4d3a-4f1b-8a7c-2e5d6f7a8b90",
"status": "active",
"created_at": "2026-04-14T11:00:00Z"
}
]/api/v1/vault/namespaces/{namespace_id}/access/eligibleList Eligible Principals
List principals that are eligible to receive grants in this namespace after applying the connection gate and namespace consumer policy.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/eligible \
-H "Authorization: Bearer {token}" -H "X-Company-Id: {company_id}"Response
200 OK[]/api/v1/vault/namespaces/{namespace_id}/access/permissionsList Namespace Permissions
List Vault permissions that can be granted from the namespace access surface. Use the returned UUID as permission_id when creating a grant.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/permissions \
-H "Authorization: Bearer {token}" -H "X-Company-Id: {company_id}"Response
200 OK[]/api/v1/vault/namespaces/{namespace_id}/access/resource-typesGet Namespace Resource Types
Return the namespace-to-credential resource-type chain plus the grantable permissions used by generic access clients.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
curl https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/resource-types \
-H "Authorization: Bearer {token}" -H "X-Company-Id: {company_id}"Response
200 OK{ "chain": [], "permissions": [] }/api/v1/vault/namespaces/{namespace_id}/access/connection-requests/{request_id}/rejectReject Connection Request
Reject a pending inbound connection request for this namespace.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
request_id* | string | Connection request ID |
Request Body
| Name | Type | Description |
|---|---|---|
reason | string | null | Optional rejection reason |
curl -X POST https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/connection-requests/{request_id}/reject \
-H "Authorization: Bearer {token}" -H "X-Company-Id: {company_id}" \
-H "Content-Type: application/json" -d '{"reason":"Not approved"}'Response
200 OK{ "id": "{request_id}", "status": "rejected" }/api/v1/vault/namespaces/{namespace_id}/access/connections/{connection_id}Revoke Connection
Revoke an active inbound namespace connection and its associated access relationship.
Bearer token required. Header: X-Company-Id. Permission: vault:permissions:namespaces:manage (on the namespace path).
Path Parameters
| Name | Type | Description |
|---|---|---|
namespace_id* | string (UUID) | Namespace ID |
connection_id* | string | Connection ID |
curl -X DELETE https://platform.ergondata.ai/api/v1/vault/namespaces/{namespace_id}/access/connections/{connection_id} \
-H "Authorization: Bearer {token}" -H "X-Company-Id: {company_id}"