> ## Documentation Index
> Fetch the complete documentation index at: https://portkey-docs-chore-bedrock-service-tier-support.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Secret References

> Reference secrets stored in external secret managers like AWS Secrets Manager, Azure Key Vault, and HashiCorp Vault instead of storing them directly in Portkey.

Secret References let you point Portkey to credentials stored in your external vault. Instead of entering keys directly in Portkey, you create a **reference**, that tells Portkey where to fetch the value at runtime.

This keeps sensitive material in infrastructure you already control and audit.

<Info>
  Available on **Enterprise** plans only. Requires:

  * Gateway version **2.2.4** or higher
  * Backend version **1.12.0** or higher (for air-gapped deployments).
</Info>

## Supported Secret Managers

| Manager             | `manager_type` value |
| ------------------- | -------------------- |
| AWS Secrets Manager | `aws_sm`             |
| Azure Key Vault     | `azure_kv`           |
| HashiCorp Vault     | `hashicorp_vault`    |

## How It Works

Secret references use a split architecture between Portkey's **control plane** and **data plane**:

1. You create a **secret reference** in Portkey via the API. The control plane stores only the reference configuration (manager type, secret path, auth config) — never the actual secret value.
2. At runtime, the **data plane** (AI Gateway) reads the reference configuration and fetches the secret directly from your external manager.
3. The control plane never fetches or sees the final secret. The data plane caches the fetched secret value for **5 minutes** to avoid hitting your secret manager on every request. After the TTL expires, the next request triggers a fresh fetch.

```mermaid theme={null}
sequenceDiagram
    participant User
    participant ControlPlane as Control Plane
    participant DataPlane as Data Plane (AI Gateway)
    participant SecretManager as Your Secret Manager
    participant LLM as LLM Provider

    User->>ControlPlane: Create secret reference (path + auth config)
    ControlPlane->>ControlPlane: Store reference config (no secret value)

    User->>DataPlane: API request using secret reference
    DataPlane->>ControlPlane: Fetch reference config
    ControlPlane-->>DataPlane: Returns reference config (path + auth)
    DataPlane->>SecretManager: Fetch actual secret using config
    SecretManager-->>DataPlane: Returns secret value
    DataPlane->>DataPlane: Cache secret (5 min TTL)
    DataPlane->>LLM: Forward request with secret

```

## Creating a Secret Reference

### From the Control Panel

1. From your admin panel, go to [**Secret References**](https://app.portkey.ai/secret-references) and click **Create**.

2. Configure the reference identity:

<Frame>
  <img src="https://mintcdn.com/portkey-docs-chore-bedrock-service-tier-support/l1jPbRNiL-6ch0TY/images/product/creating-secret-references.png?fit=max&auto=format&n=l1jPbRNiL-6ch0TY&q=85&s=36c1ba59301bc4027648ba181b98d953" alt="Creating Secret References" width="2938" height="1376" data-path="images/product/creating-secret-references.png" />
</Frame>

* **Name**: A name for this reference
* **Slug**: Unique identifier, auto-generated from name if not added. Pattern: `^[a-zA-Z0-9_-]+$`
* **Description**: Optional context about this reference's purpose

3. Choose your external vault from the supported options:
   * AWS Secrets Manager
   * Azure Key Vault
   * HashiCorp Vault

4. Select the authentication type for your chosen manager and add the required details.

5. Secret Location:
   * **Secret Path**: Add the Secret name from the external manager
   * **Secret Key** (optional): Add the specific key within the secret

<Frame>
  <img src="https://mintcdn.com/portkey-docs-chore-bedrock-service-tier-support/l1jPbRNiL-6ch0TY/images/product/secret-location-example.png?fit=max&auto=format&n=l1jPbRNiL-6ch0TY&q=85&s=0bcf49ec21da61314e3fdf9cdc0dd8ca" alt="Secret Location Configuration" width="1884" height="472" data-path="images/product/secret-location-example.png" />
</Frame>

### Via Admin APIs

Send a `POST` request to `/v1/secret-references` with the following body:

```json theme={null}
{
  "name": "prod-openai-key",
  "manager_type": "aws_sm",
  "auth_config": {
    "aws_auth_type": "accessKey",
    "aws_access_key_id": "AKIA...",
    "aws_secret_access_key": "wJalr...",
    "aws_region": "us-east-1"
  },
  "secret_path": "prod/openai/api-key",
  "secret_key": "OPENAI_API_KEY"
}
```

| Field                  | Type           | Required | Description                                                                                                 |
| ---------------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| `name`                 | string         | Yes      | Display name (1–255 chars).                                                                                 |
| `slug`                 | string         | No       | Unique identifier. Auto-generated from name if omitted. Pattern: `^[a-zA-Z0-9_-]+$`.                        |
| `description`          | string \| null | No       | Max 1024 chars.                                                                                             |
| `manager_type`         | string         | Yes      | `aws_sm`, `azure_kv`, or `hashicorp_vault`.                                                                 |
| `auth_config`          | object         | Yes      | Auth credentials for connecting to the manager. See [Auth Config](#auth-config) below.                      |
| `secret_path`          | string         | Yes      | Path to the secret in the external manager.                                                                 |
| `secret_key`           | string \| null | No       | Specific key within the secret (when the secret holds multiple key-value pairs).                            |
| `allow_all_workspaces` | boolean        | No       | Default `true`. Grant access to all workspaces.                                                             |
| `allowed_workspaces`   | string\[]      | No       | Restrict access to specific workspace UUIDs or slugs. Mutually exclusive with `allow_all_workspaces: true`. |
| `tags`                 | object \| null | No       | Key-value metadata tags.                                                                                    |

## Updating a Secret Reference

Send a `PUT` request to `/v1/secret-references/:id` with only the fields you want to change. At least one field must be provided.

`auth_config` updates are **merged** with the existing config - you don't need to resend the full object.

Setting `allow_all_workspaces: true` purges any workspace-specific mappings. Providing `allowed_workspaces` automatically sets `allow_all_workspaces` to `false`.

## Deleting a Secret Reference

Send a `DELETE` request to `/v1/secret-references/:id`.

It will fail if the secret reference is currently in use by any integrations - remove those associations first.

## Workspace Scoping

By default, a secret reference is accessible from **all workspaces** in your organisation. To restrict access:

* Pass `allowed_workspaces` with an array of workspace UUIDs or slugs when creating or updating the reference.
* This automatically disables `allow_all_workspaces`.

To revert to org-wide access, set `allow_all_workspaces: true` - this purges all workspace-specific mappings.

## Auth Config

The `auth_config` schema depends on the `manager_type` you choose.

<Tabs>
  <Tab title="AWS Secrets Manager">
    ### Access Key

    | Field                   | Type          | Required |
    | ----------------------- | ------------- | -------- |
    | `aws_auth_type`         | `"accessKey"` | Yes      |
    | `aws_access_key_id`     | string        | Yes      |
    | `aws_secret_access_key` | string        | Yes      |
    | `aws_region`            | string        | Yes      |

    ### Assumed Role

    Use this when Portkey should assume an IAM role in your account.

    | Field             | Type            | Required |
    | ----------------- | --------------- | -------- |
    | `aws_auth_type`   | `"assumedRole"` | Yes      |
    | `aws_role_arn`    | string          | Yes      |
    | `aws_external_id` | string \| null  | No       |
    | `aws_region`      | string          | Yes      |

    ### Service Role

    Uses Portkey's own service role. Requires your secret's resource policy to grant Portkey access.

    | Field           | Type            | Required |
    | --------------- | --------------- | -------- |
    | `aws_auth_type` | `"serviceRole"` | Yes      |
    | `aws_region`    | string          | No       |
  </Tab>

  <Tab title="Azure Key Vault">
    ### Entra (Service Principal)

    | Field                       | Type      | Required |
    | --------------------------- | --------- | -------- |
    | `azure_auth_mode`           | `"entra"` | Yes      |
    | `azure_entra_tenant_id`     | string    | Yes      |
    | `azure_entra_client_id`     | string    | Yes      |
    | `azure_entra_client_secret` | string    | Yes      |
    | `azure_vault_url`           | url       | Yes      |

    ### Managed Identity

    | Field                     | Type        | Required |
    | ------------------------- | ----------- | -------- |
    | `azure_auth_mode`         | `"managed"` | Yes      |
    | `azure_managed_client_id` | string      | No       |
    | `azure_vault_url`         | url         | Yes      |

    ### Default Credentials

    | Field             | Type        | Required |
    | ----------------- | ----------- | -------- |
    | `azure_auth_mode` | `"default"` | Yes      |
    | `azure_vault_url` | url         | Yes      |
  </Tab>

  <Tab title="HashiCorp Vault">
    ### Token

    | Field             | Type      | Required |
    | ----------------- | --------- | -------- |
    | `vault_auth_type` | `"token"` | Yes      |
    | `vault_addr`      | url       | Yes      |
    | `vault_token`     | string    | Yes      |
    | `vault_namespace` | string    | No       |

    ### AppRole

    | Field             | Type        | Required |
    | ----------------- | ----------- | -------- |
    | `vault_auth_type` | `"approle"` | Yes      |
    | `vault_addr`      | url         | Yes      |
    | `vault_role_id`   | string      | Yes      |
    | `vault_secret_id` | string      | Yes      |
    | `vault_namespace` | string      | No       |

    ### Kubernetes

    | Field             | Type           | Required |
    | ----------------- | -------------- | -------- |
    | `vault_auth_type` | `"kubernetes"` | Yes      |
    | `vault_addr`      | url            | Yes      |
    | `vault_role`      | string         | Yes      |
    | `vault_namespace` | string         | No       |
  </Tab>
</Tabs>

## Secret Mappings

Secret mappings allow integrations to dynamically resolve secrets from secret references at runtime, instead of storing credentials directly. The `secret_mappings` field is an optional JSON array accepted on create and update in **Integrations**.

### Schema

Each entry in the `secret_mappings` array:

| Field                 | Type           | Required | Description                                                                                                               |
| --------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `target_field`        | string         | Yes      | The field on the entity that should be populated from the secret reference. Must be unique within the array.              |
| `secret_reference_id` | string         | Yes      | UUID or slug of the secret reference to resolve. Must belong to the same organisation and be accessible by the workspace. |
| `secret_key`          | string \| null | No       | Override the `secret_key` defined on the secret reference. Use to pick a specific key from a multi-value secret.          |

### From the Control Panel

If you're storing provider API keys in your vault, map your secrets in LLM Integrations:

1. While creating a new LLM integration (or editing an existing one), you'll see a toggle. Switch to **Secret Ref** to use the key via your vault.

<Frame>
  <img src="https://mintcdn.com/portkey-docs-chore-bedrock-service-tier-support/l1jPbRNiL-6ch0TY/images/product/secret-mapping.png?fit=max&auto=format&n=l1jPbRNiL-6ch0TY&q=85&s=bcedabb3fe1ad61d2b6298884ada8e58" alt="Secret Mapping in Integrations" width="2048" height="1334" data-path="images/product/secret-mapping.png" />
</Frame>

2. Select the secret reference. Optionally, provide a **Secret Key** if the reference contains multiple values.

<Frame>
  <img src="https://mintcdn.com/portkey-docs-chore-bedrock-service-tier-support/l1jPbRNiL-6ch0TY/images/product/secret-vault-example.png?fit=max&auto=format&n=l1jPbRNiL-6ch0TY&q=85&s=834092d16c5503a2d93d661501ba4479" alt="Secret Vault Configuration" width="2434" height="594" data-path="images/product/secret-vault-example.png" />
</Frame>

### Via Admin APIs

### Valid `target_field` Values

**Integrations** (`POST /v1/integrations`, `PUT /v1/integrations/:integrationId`)

| target\_field            | Description                                                                                                                          |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `key`                    | The provider API key. When mapped, the `key` body field can be omitted.                                                              |
| `configurations.<field>` | Any provider-specific configuration field (e.g. `configurations.aws_secret_access_key`, `configurations.azure_entra_client_secret`). |

### Example

```json theme={null}
{
  "secret_mappings": [
    {
      "target_field": "key",
      "secret_reference_id": "my-aws-api-key"
    },
    {
      "target_field": "configurations.aws_secret_access_key",
      "secret_reference_id": "aws-credentials-ref",
      "secret_key": "secret_access_key"
    }
  ]
}
```

### Validation Rules

* `secret_mappings` must be an array (if provided).
* Each `target_field` must be one of the allowed fields/prefixes for the entity type.
* No duplicate `target_field` values within the array.
* Each `secret_reference_id` must reference an existing, active secret reference in the same organisation.
* If the entity is workspace-scoped, the secret reference must be accessible to that workspace (either `allow_all_workspaces: true` or explicitly mapped).
* On create, `target_field` values with the `configurations.` prefix are auto-normalized — you can pass just the field name without the prefix and it will be prepended.

### Behavior

* At gateway runtime, mapped fields are resolved from the external secret manager using the referenced secret reference's `auth_config`, `secret_path`, and the mapping's `secret_key` (or the secret reference's default `secret_key`).
* When a `target_field` of `key` is mapped, the `key` field on the entity becomes optional during creation.
* Secret mappings are returned in GET responses for integrations.

***

## Sensitive Field Masking

When you retrieve a secret reference via the API, sensitive `auth_config` fields are automatically masked. The original field is replaced with a `masked_` prefixed version containing a truncated value.

| Original Field              | Masked Field                       |
| --------------------------- | ---------------------------------- |
| `aws_secret_access_key`     | `masked_aws_secret_access_key`     |
| `aws_access_key_id`         | `masked_aws_access_key_id`         |
| `aws_role_arn`              | `masked_aws_role_arn`              |
| `aws_external_id`           | `masked_aws_external_id`           |
| `azure_entra_client_secret` | `masked_azure_entra_client_secret` |
| `vault_token`               | `masked_vault_token`               |
| `vault_secret_id`           | `masked_vault_secret_id`           |

## Access Requirements

* **Authentication**: `x-portkey-api-key` header.
* **RBAC Role**: `OWNER` or `ADMIN`.

***

## API Reference

<Card title="Create Secret Reference" href="/api-reference/admin-api/control-plane/secret-references/create-secret-reference" />

<Card title="List Secret References" href="/api-reference/admin-api/control-plane/secret-references/list-secret-references" />

<Card title="Retrieve Secret Reference" href="/api-reference/admin-api/control-plane/secret-references/retrieve-secret-reference" />

<Card title="Update Secret Reference" href="/api-reference/admin-api/control-plane/secret-references/update-secret-reference" />

<Card title="Delete Secret Reference" href="/api-reference/admin-api/control-plane/secret-references/delete-secret-reference" />
