> For the complete documentation index, see [llms.txt](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults/secret-references-api.md).

# Using secret references via API

{% hint style="info" %}
**Early Access**: Secrets Vaults is not enabled by default. Contact Veza support to enable the feature for your organization before using the API workflows on this page.
{% endhint %}

The Veza API exposes the same vault-injection mechanism the UI uses. When you create or update a provider through the API, you can attach a `secret_references` entry that points the provider's credential fields at a secret in your external vault. Use the API path for bulk provisioning, IaC and Terraform workflows, programmatic credential rotation, or any case where you keep integration credentials in an external vault instead of sending them inline.

The same field is available on data sources: when a provider has multiple data sources that each need their own credentials, you can attach `secret_references` to a specific data source instead of the parent provider. This is used for integrations such as Anthropic Claude Managed Agents, where each discovered workspace becomes its own data source with its own workspace API key.

For UI-driven configuration and External Secrets Vault enablement, see the main [Secrets Vaults](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults.md) guide.

## Understanding the `secret_references` field

`secret_references` is a repeated field of `SecretReference` objects on both the `Provider` and `DataSource` resources. Each entry has the following shape:

| Field                    | Type                    | Description                                                                                                                                |
| ------------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                     | string                  | Server-assigned identifier for the reference. Output-only; do not set on create.                                                           |
| `secret_id`              | string                  | The name (or ID) of the secret as it exists in the external vault.                                                                         |
| `secret_mapping.type`    | enum (`JSON`, `SIMPLE`) | How to interpret the secret value. See below.                                                                                              |
| `secret_mapping.mapping` | string                  | For `SIMPLE`, the single provider field this secret fills. Not used for `JSON` — Veza maps the secret's JSON keys to fields automatically. |
| `vault_id`               | string                  | The Veza ID of the secrets vault the secret lives in. Look up with `GET /api/v1/secretsvaults`.                                            |
| `vault`                  | object                  | Embedded vault details such as name and provider. Output-only; populated by the server on read.                                            |

{% hint style="warning" %}
A provider holds at most **one** provider-level `secret_references` entry, and each data source holds at most one of its own. To fill several credential fields from the vault, use a single `type: JSON` secret whose keys are the field names — not multiple references.
{% endhint %}

## `SIMPLE` versus `JSON` secret mapping types

The `secret_mapping.type` controls how Veza interprets the value stored in the vault.

`SIMPLE` means the entire secret value in the vault is the credential value for a single field.

* For example, if the vault secret named `prod-okta-token` contains the literal token string, populate the integration's `token` field with `type: SIMPLE` and `mapping: token`.

`JSON`, the default, means the secret value in the vault is a JSON object whose keys are the provider field names Veza should fill. Veza reads every key and maps it to the field of the same name, so one reference populates all of the provider's vault-eligible fields at once. `mapping` is not used with `JSON`.

* This matches the UI workflow: a single vault secret holds all of the integration's credentials as one JSON object.
* For example, if the vault secret named `prod-ad-credentials` contains `{"username": "...", "password": "...", "ldaps_certificate": "..."}`, you attach one `secret_references` entry with `type: JSON`. Veza fills `username`, `password`, and `ldaps_certificate` from the object's keys. For built-in integrations, a key that matches no provider field fails the extraction, so include only the fields the integration expects.

## End-to-end workflow

A typical API workflow involves three steps:

1. Find the vault ID
2. Create the secret in the external vault
3. Create or update the Veza provider with `secret_references` that point at the secret.

### 1. Look up the vault ID

List the vaults registered with Veza to find the ID of the vault you want to use:

```bash
curl -X GET "$BASE_URL/api/v1/secretsvaults" \
  -H "Authorization: Bearer $VEZA_TOKEN"
```

The response contains a `values` array of `SecretsVault` objects, each with an `id` and a `name`. Use the `id` as the `vault_id` in the next step.

> To create a new vault, follow the steps in the main [Secrets Vaults](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults.md#configure-vault-access-on-insight-point) guide. Note that vault registration occurs through the Insight Point YAML configuration, not the Veza API.

### 2. Create the secret in the external vault

Create the secret inside your external vault (such as Azure Key Vault) using that vault's own tools or API. The secret's name becomes the `secret_id` in the next step. Format the secret value as JSON if you plan to use `type: JSON` mapping, or as a plain string for `type: SIMPLE`. See [Create external secrets in Azure Key Vault](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults.md#create-external-secrets-in-azure-key-vault) for the JSON shapes per integration type.

### 3. Create or update the provider with `secret_references`

Each provider type has its own endpoint. Send a `POST` to create a new provider, or a `PATCH` to update an existing one, with the `secret_references` array populated:

```bash
curl -X POST "$BASE_URL/api/v1/providers/activedirectory" \
  -H "Authorization: Bearer $VEZA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Prod AD",
    "data_plane_id": "<insight-point-id>",
    "host": "ad.example.com",
    "port": 636,
    "secret_references": [
      {
        "secret_id": "prod-ad-credentials",
        "vault_id": "<vault-id-from-step-1>",
        "secret_mapping": { "type": "JSON" }
      }
    ]
  }'
```

The `prod-ad-credentials` vault secret is a single JSON object, `{"username": "...", "password": "...", "ldaps_certificate": "..."}`. The one `type: JSON` reference fills all three fields from its keys; you do not create a reference per field.

To update the `secret_references` on an existing provider, send a `PATCH` to the per-type provider endpoint with the new array. The request body shape mirrors the `POST` body for the same type.

## Per-integration mapping reference

For `type: JSON`, the vault secret's keys must match the field names documented for each integration in the main [Secrets Vaults guide](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults.md#create-external-secrets-in-azure-key-vault). The table below summarizes the keys each integration expects.

| Integration      | Endpoint (POST)                     | JSON keys the vault secret must contain                                       |
| ---------------- | ----------------------------------- | ----------------------------------------------------------------------------- |
| Active Directory | `/api/v1/providers/activedirectory` | `username`, `password`, `ldaps_certificate`                                   |
| Azure            | `/api/v1/providers/azure`           | `client_id`, `client_secret`, `auth_certificate`, `auth_certificate_password` |
| Okta (OAuth)     | `/api/v1/providers/okta`            | `client_id`, `private_key_id`, `private_key`                                  |
| Okta (API Token) | `/api/v1/providers/okta`            | `token`                                                                       |
| Custom (OAA)     | `/api/v1/providers/custom`          | Connector-specific. See note below.                                           |

Include only the keys the integration needs; you attach them as one `type: JSON` secret via a single `secret_references` entry, and Veza maps each key to the field of the same name.

### Custom (OAA) mapping values

For Custom (OAA) providers, the available `mapping` values are defined by the connector's own configuration schema, not by a fixed list. Each OAA connector ships a `configuration_definition` that declares the named properties Veza expects when it runs that connector's discovery and extraction.

For a built-in OAA connector, consult the connector's documentation page for the names of its configuration and secret properties. For a user-defined custom OAA connector, the property names are the ones you declared in the connector's `configuration_definition`. Custom (OAA) providers accept both forms: `type: SIMPLE`, where one secret value fills the single property named by `secret_mapping.mapping`, and `type: JSON`, where the vault secret is a JSON object whose keys are the property names. Unlike built-in integrations, a Custom (OAA) provider-level `JSON` secret ignores keys that are not declared vault-sourced properties instead of failing.

## Data source level secret references

To attach a secret reference to a specific data source rather than the whole provider, send a `PATCH` to the data source endpoint. `PATCH` has partial-update semantics: fields omitted from the request body are left unchanged on the data source.

```bash
curl -X PATCH "$BASE_URL/api/v1/providers/datasources/<datasource-id>" \
  -H "Authorization: Bearer $VEZA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "secret_references": [
      {
        "secret_id": "anthropic-workspace-alpha-key",
        "vault_id": "<vault-id>",
        "secret_mapping": { "type": "SIMPLE", "mapping": "workspace_api_key" }
      }
    ]
  }'
```

To **clear** all secret references on a data source, send a `PUT` to the same path with `secret_references` set to an empty array. `PUT` has full-replacement semantics, where an empty array clears the existing references. A `PATCH` with an empty `secret_references` array is treated as "not provided" and leaves the existing references unchanged.

Provider-level and data-source-level `secret_references` populate different credential fields. For providers, `secret_references` injects values into provider-scope fields, which apply across all of the provider's data sources (for example, an admin key used to enumerate workspaces). A data source's `secret_references` injects values into fields defined on that data source itself.

These two field sets are distinct; no integration today has a credential field that exists at both levels. Provider-level and data-source-level references do not override each other.

For example, the Anthropic Claude Managed Agents integration implements `admin_api_key` as a provider-scope field to enumerate workspaces across the organization. `workspace_api_key` is a separate data-source-scope field that authenticates extraction for a specific workspace. Integration includes both attaching the admin key to the provider's `secret_references`, and each workspace key to the matching data source's `secret_references`.

The native OpenAI integration follows the same pattern: `admin_api_key` is a provider-scope field that enumerates projects, and `project_api_key` is a data-source-scope field that authenticates extraction for a specific project. After the Admin API key discovers your projects, Veza creates a data source for each one — identified by an ID of the form `<project_id>:openai_project` — in an *awaiting credentials* state. `PATCH` that data source with its project-scoped key:

```bash
curl -X PATCH "$BASE_URL/api/v1/providers/datasources/<datasource-id>" \
  -H "Authorization: Bearer $VEZA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "secret_references": [
      {
        "secret_id": "openai-project-alpha-key",
        "vault_id": "<vault-id>",
        "secret_mapping": { "type": "SIMPLE", "mapping": "project_api_key" }
      }
    ]
  }'
```

Here `secret_id` is the name of the secret as it exists in your external vault, `vault_id` is the Veza vault ID from `GET /api/v1/secretsvaults` (see [Look up the vault ID](#1-look-up-the-vault-id)), and `secret_mapping.mapping` must be `project_api_key`. The data source is identified by its ID in the request path, not by `secret_id`.

## Interactive API reference

Try the relevant endpoints directly:

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/v1/secretsvaults" method="get" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-e3fba3abb5b679c13fe60a1cae0981015167f16e%2Fopenapi.yaml?alt=media)
{% endopenapi %}

{% openapi src="/files/Aco9gj4MY2XoNiD4zIjr" path="/api/v1/providers/datasources/{id}" method="patch" %}
[openapi.yaml](https://1967633068-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZDkWMxox3pekd0NsZJ%2Fuploads%2Fgit-blob-e3fba3abb5b679c13fe60a1cae0981015167f16e%2Fopenapi.yaml?alt=media)
{% endopenapi %}

## See also

* [Secrets Vaults](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults.md) - main UI configuration guide
* [Azure Key Vault configuration reference](/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults/azure-key-vault.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/integrations/connectivity/secrets-vaults/secret-references-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
