---
title: Cloudflare Secrets Store
description: Use Secrets Store to encrypt and store sensitive information as secrets that are securely reusable across your Cloudflare account.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Cloudflare Secrets Store

Encrypt and store sensitive information as secrets that are securely reusable across your account.

 Available in open beta 

Cloudflare Secrets Store is a secure, centralized location in which account-level secrets are stored and managed. The secrets are securely encrypted and stored across all [Cloudflare data centers ↗](https://www.cloudflare.com/network/).

Secrets Store is currently compatible with [Cloudflare Workers](https://developers.cloudflare.com/secrets-store/integrations/workers/) and [AI Gateway](https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/). Integrations with other products will be added in the future.

China availability

Secrets Store is unavailable in the [Cloudflare China Network](https://developers.cloudflare.com/china-network/), operated by Cloudflare's partner JD Cloud.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}}]}
```

---

---
title: Secrets Store access control
description: Learn about role-based access control with Cloudflare Secrets Store
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Secrets Store access control

Secrets Store allows security administrators to have more control by implementing role-based access. For details about roles at Cloudflare, refer to [Fundamentals](https://developers.cloudflare.com/fundamentals/manage-members/).

Availability

While all Cloudflare accounts will have access to the Secrets Store section on the dashboard, only users with the necessary permissions will be able to interact with it, as described below.

## Relevant roles

Refer to the list below for default role definitions.

#### Super Administrator

* Can create, edit, duplicate, delete, and view secrets metadata.
* Can [add a Secrets Store binding to a Worker](https://developers.cloudflare.com/secrets-store/integrations/workers/).
* Can [create an association between a secret and an AI gateway](https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/).

#### Secrets Store Admin

* Can create, edit, duplicate, delete, and view secrets metadata.

#### Secrets Store Deployer

* Can view secrets metadata but cannot create, edit, duplicate, nor delete secrets.
* Can [add a Secrets Store binding to a Worker](https://developers.cloudflare.com/secrets-store/integrations/workers/).
* Can [create an association between a secret and an AI gateway](https://developers.cloudflare.com/ai-gateway/configuration/bring-your-own-keys/).

#### Secrets Store Reporter

* Can view secrets metadata.
* Cannot perform any actions (create, edit, duplicate, delete secrets), nor use Secrets Store integrations with other Cloudflare products.

## API token permissions

The following API token permissions can also be used to grant access to Secrets Store resources.

* **Account Secrets Store Edit**: Allows a user to create, edit, duplicate, or delete secrets.
* **Account Secrets Store Read**: Allows a user to view secrets metadata.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}},{"@type":"ListItem","position":3,"item":{"@id":"/secrets-store/access-control/","name":"Secrets Store access control"}}]}
```

---

---
title: Manage account secrets
description: Learn about different operations to manage your secrets in Cloudflare Secrets Store.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Manage account secrets

Secrets can be API tokens, public/private keys, authorization keys, passwords, or even code variables. The only limitation is that a secret must be a string that does not exceed 1024 bytes.

Once a secret is added to the Secrets Store, it can no longer be decrypted or accessed via API or on the dashboard. Only the service associated with a given secret will be able to access it.

## Limits

Customers who create a secrets store in the open beta can have up to 100 secrets per account. Also, there can only be one store per account.

Production secrets

If you use [Wrangler](https://developers.cloudflare.com/secrets-store/manage-secrets/how-to/#manage-via-wrangler), there is a difference between production secrets and secrets that are only created locally (without the `--remote` flag). The limit of 100 secrets per account only considers production secrets.

## Resources

* [Manage via Wrangler](https://developers.cloudflare.com/workers/wrangler/commands/secrets-store/#secrets-store-secret)
* [Create a secret](https://developers.cloudflare.com/secrets-store/manage-secrets/how-to/#create-a-secret)
* [Duplicate a secret](https://developers.cloudflare.com/secrets-store/manage-secrets/how-to/#duplicate-a-secret)
* [Edit a secret](https://developers.cloudflare.com/secrets-store/manage-secrets/how-to/#edit-a-secret)
* [Delete a secret](https://developers.cloudflare.com/secrets-store/manage-secrets/how-to/#delete-a-secret)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}},{"@type":"ListItem","position":3,"item":{"@id":"/secrets-store/manage-secrets/","name":"Manage account secrets"}}]}
```

---

---
title: How to
description: Create, update, duplicate, and delete secrets using the dashboard, API, or Wrangler.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# How to

Refer to the sections below to learn about common actions you might want to take when managing your data in Secrets Store.

You must have a [Super Administrator or Secrets Store Admin role](https://developers.cloudflare.com/secrets-store/access-control/) within your Cloudflare account.

## Manage via Wrangler

[Wrangler](https://developers.cloudflare.com/workers/wrangler/) is a command-line interface (CLI) that allows you to manage [Cloudflare Workers](https://developers.cloudflare.com/workers/) projects. Refer to [Wrangler commands](https://developers.cloudflare.com/workers/wrangler/commands/secrets-store/#secrets-store-secret) for guidance on how to use it with Secrets Store.

## Create a secret

* [ Dashboard ](#tab-panel-8188)
* [ API ](#tab-panel-8189)

1. In the Cloudflare dashboard, go to the **Secrets Store** page.  
[ Go to **Secrets Store** ](https://dash.cloudflare.com/?to=/:account/secrets-store)
2. Select **Create secret**.
3. Fill in the required fields. Note that, once the secret is saved, the secret value will no longer be available for viewing.
4. (Optional) Select **Add additional secret** to create more than one secret at a time.
5. Select **Save** to confirm.

Note

A secret `name` cannot contain spaces. Refer to [Secrets Store API](https://developers.cloudflare.com/api/resources/secrets%5Fstore/) for the full API documentation.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Secrets Store Write`

Create a secret

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets" \

  --request POST \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY" \

  --json '[

    {

        "name": "<MY_SECRET_NAME>",

        "value": "<SECRET_VALUE>",

        "scopes": [

            "workers"

        ],

        "comment": ""

    },

    {

        "name": "<MY_SECRET_NAME_2>",

        "value": "<SECRET_VALUE>",

        "scopes": [

            "workers"

        ],

        "comment": ""

    }

  ]'


```

## Duplicate a secret

Duplicate a secret to keep the same secret value but change name, scope, or comments.

* [ Dashboard ](#tab-panel-8182)
* [ API ](#tab-panel-8183)

1. In the Cloudflare dashboard, go to the **Secrets Store** page.  
[ Go to **Secrets Store** ](https://dash.cloudflare.com/?to=/:account/secrets-store)
2. Search for the secret you would like to duplicate within the existing secrets list.
3. Select the three dots next to the secret and choose **Duplicate**.
4. Edit the **Secret name**, **Permission scope**, or **Comment**, according to your needs.
5. Select **Save** to confirm.

Note

A secret `name` cannot contain spaces. Refer to [Secrets Store API](https://developers.cloudflare.com/api/resources/secrets%5Fstore/) for the full API documentation.

Terminal window

```

curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID/duplicate \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

--header "Content-Type: application/json" \

--data '{

    "name":"<NEW_DUPLICATE_NAME>",

    "scopes":["workers"],

    "comment":""

}'


```

## Edit a secret

Edit a secret to replace an existing value with a new one.

Warning

This action will cause the replacement in all services using the secret.

You can also edit the secret **Permission scope** and **Comment**.

* [ Dashboard ](#tab-panel-8184)
* [ API ](#tab-panel-8185)

1. In the Cloudflare dashboard, go to the **Secrets Store** page.  
[ Go to **Secrets Store** ](https://dash.cloudflare.com/?to=/:account/secrets-store)
2. Search for the secret you would like to edit within the existing secrets list.
3. Select the three dots next to the secret and choose **Edit**.
4. Edit the available fields according to your needs and select **Save** to confirm.

Refer to [Secrets Store API](https://developers.cloudflare.com/api/resources/secrets%5Fstore/) for the full API documentation.

Terminal window

```

curl --request PATCH \

https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

--header "Content-Type: application/json" \

--data '{

    "comment":"<NEW_COMMENT>",

    "value":"<NEW_SECRET_VALUE>",

    "scopes":["workers"]

}'


```

## Delete a secret

Warning

Before deleting a secret, make sure it is not deployed in your [Workers applications ↗](https://dash.cloudflare.com/?to=/:account/workers-and-pages/) or [AI gateways ↗](https://dash.cloudflare.com/?to=/:account/ai/ai-gateway).

* [ Dashboard ](#tab-panel-8186)
* [ API ](#tab-panel-8187)

1. In the Cloudflare dashboard, go to the **Secrets Store** page.  
[ Go to **Secrets Store** ](https://dash.cloudflare.com/?to=/:account/secrets-store)
2. Search for the secret you would like to delete within the existing secrets list.
3. Select the three dots next to the secret and choose **Delete**.
4. Type in the secret name and select **Delete** to confirm.

Refer to [Secrets Store API](https://developers.cloudflare.com/api/resources/secrets%5Fstore/) for the full API documentation.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Secrets Store Write`

Delete a secret

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID" \

  --request DELETE \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY"


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}},{"@type":"ListItem","position":3,"item":{"@id":"/secrets-store/manage-secrets/","name":"Manage account secrets"}},{"@type":"ListItem","position":4,"item":{"@id":"/secrets-store/manage-secrets/how-to/","name":"How to"}}]}
```

---

---
title: Audit logs
description: Actions logged for Secrets Store operations, including create, update, and delete.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Audit logs

[Audit logs](https://developers.cloudflare.com/fundamentals/account/account-security/review-audit-logs/) provide a comprehensive summary of changes made within your Cloudflare account. This page lists the actions that are logged for Secrets Store.

* Access
* Create  
   * Duplicating a secret is presented as a `create` log with a field `duplicated_from_id`.
* Update  
   * A boolean `"value_modified": true` is presented when the secret value is edited.
* Delete

For information on how to access and use audit logs, refer to [Fundamentals](https://developers.cloudflare.com/fundamentals/account/account-security/review-audit-logs/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}},{"@type":"ListItem","position":3,"item":{"@id":"/secrets-store/audit-logs/","name":"Audit logs"}}]}
```

---

# Secrets Store

# Stores

## List account stores

**get** `/accounts/{account_id}/secrets_store/stores`

Lists all the stores in an account

### Path Parameters

- `account_id: string`

  Account Identifier

### Query Parameters

- `direction: optional "asc" or "desc"`

  Direction to sort objects

  - `"asc"`

  - `"desc"`

- `order: optional "name" or "comment" or "created" or 2 more`

  Order secrets by values in the given field

  - `"name"`

  - `"comment"`

  - `"created"`

  - `"modified"`

  - `"status"`

- `page: optional number`

  Page number

- `per_page: optional number`

  Number of objects to return per page

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional array of object { id, created, modified, 2 more }`

  - `id: string`

    Store Identifier

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the store

  - `account_id: optional string`

    Account Identifier

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": [
    {
      "id": "023e105f4ecef8ad9ca31a8372d0c353",
      "created": "2023-09-21T18:56:32.624632Z",
      "modified": "2023-09-21T18:56:32.624632Z",
      "name": "service_x_keys",
      "account_id": "985e105f4ecef8ad9ca31a8372d0c353"
    }
  ],
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Create a store

**post** `/accounts/{account_id}/secrets_store/stores`

Creates a store in the account

### Path Parameters

- `account_id: string`

  Account Identifier

### Body Parameters

- `name: string`

  The name of the store

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional object { id, created, modified, 2 more }`

  - `id: string`

    Store Identifier

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the store

  - `account_id: optional string`

    Account Identifier

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores \
    -H 'Content-Type: application/json' \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -d '{
          "name": "service_x_keys"
        }'
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {
    "id": "023e105f4ecef8ad9ca31a8372d0c353",
    "created": "2023-09-21T18:56:32.624632Z",
    "modified": "2023-09-21T18:56:32.624632Z",
    "name": "service_x_keys",
    "account_id": "985e105f4ecef8ad9ca31a8372d0c353"
  },
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Delete a store

**delete** `/accounts/{account_id}/secrets_store/stores/{store_id}`

Deletes a single store

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional unknown`

  Result is null for delete operations.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID \
    -X DELETE \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {}
}
```

## Domain Types

### Store List Response

- `StoreListResponse object { id, created, modified, 2 more }`

  - `id: string`

    Store Identifier

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the store

  - `account_id: optional string`

    Account Identifier

### Store Create Response

- `StoreCreateResponse object { id, created, modified, 2 more }`

  - `id: string`

    Store Identifier

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the store

  - `account_id: optional string`

    Account Identifier

### Store Delete Response

- `StoreDeleteResponse = unknown`

  Result is null for delete operations.

# Secrets

## List store secrets

**get** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets`

Lists all store secrets

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

### Query Parameters

- `direction: optional "asc" or "desc"`

  Direction to sort objects

  - `"asc"`

  - `"desc"`

- `order: optional "name" or "comment" or "created" or 2 more`

  Order secrets by values in the given field

  - `"name"`

  - `"comment"`

  - `"created"`

  - `"modified"`

  - `"status"`

- `page: optional number`

  Page number

- `per_page: optional number`

  Number of objects to return per page

- `scopes: optional array of array of string`

  Only secrets with the given scopes will be returned

- `search: optional string`

  Search secrets using a filter string, filtering across name and comment

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional array of object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": [
    {
      "id": "3fd85f74b32742f1bff64a85009dda07",
      "created": "2023-09-21T18:56:32.624632Z",
      "modified": "2023-09-21T18:56:32.624632Z",
      "name": "MY_API_KEY",
      "status": "pending",
      "store_id": "023e105f4ecef8ad9ca31a8372d0c353",
      "comment": "info about my secret",
      "scopes": [
        "workers",
        "ai_gateway",
        "dex",
        "access"
      ]
    }
  ],
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Get a secret by ID

**get** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets/{secret_id}`

Returns details of a single secret

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

- `secret_id: string`

  Secret identifier tag.

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {
    "id": "3fd85f74b32742f1bff64a85009dda07",
    "created": "2023-09-21T18:56:32.624632Z",
    "modified": "2023-09-21T18:56:32.624632Z",
    "name": "MY_API_KEY",
    "status": "pending",
    "store_id": "023e105f4ecef8ad9ca31a8372d0c353",
    "comment": "info about my secret",
    "scopes": [
      "workers",
      "ai_gateway",
      "dex",
      "access"
    ]
  },
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Create a secret

**post** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets`

Creates a secret in the account

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

### Body Parameters

- `body: array of object { name, scopes, value, comment }`

  - `name: string`

    The name of the secret

  - `scopes: array of string`

    The list of services that can use this secret.

  - `value: string`

    The value of the secret. Maximum 64 KiB (65,536 bytes). Note that this is 'write only' - no API response will provide this value, it is only used to create/modify secrets.

  - `comment: optional string`

    Freeform text describing the secret

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional array of object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets \
    -H 'Content-Type: application/json' \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -d '[
          {
            "name": "MY_API_KEY",
            "scopes": [
              "workers",
              "ai_gateway",
              "dex",
              "access"
            ],
            "value": "api-token-secret-123",
            "comment": "info about my secret"
          }
        ]'
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": [
    {
      "id": "3fd85f74b32742f1bff64a85009dda07",
      "created": "2023-09-21T18:56:32.624632Z",
      "modified": "2023-09-21T18:56:32.624632Z",
      "name": "MY_API_KEY",
      "status": "pending",
      "store_id": "023e105f4ecef8ad9ca31a8372d0c353",
      "comment": "info about my secret",
      "scopes": [
        "workers",
        "ai_gateway",
        "dex",
        "access"
      ]
    }
  ],
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Patch a secret

**patch** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets/{secret_id}`

Updates a single secret

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

- `secret_id: string`

  Secret identifier tag.

### Body Parameters

- `comment: optional string`

  Freeform text describing the secret

- `scopes: optional array of string`

  The list of services that can use this secret.

- `value: optional string`

  The value of the secret. Maximum 64 KiB (65,536 bytes). Note that this is 'write only' - no API response will provide this value, it is only used to create/modify secrets.

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID \
    -X PATCH \
    -H 'Content-Type: application/json' \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -d '{
          "comment": "info about my secret",
          "scopes": [
            "workers",
            "ai_gateway",
            "dex",
            "access"
          ],
          "value": "api-token-secret-123"
        }'
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {
    "id": "3fd85f74b32742f1bff64a85009dda07",
    "created": "2023-09-21T18:56:32.624632Z",
    "modified": "2023-09-21T18:56:32.624632Z",
    "name": "MY_API_KEY",
    "status": "pending",
    "store_id": "023e105f4ecef8ad9ca31a8372d0c353",
    "comment": "info about my secret",
    "scopes": [
      "workers",
      "ai_gateway",
      "dex",
      "access"
    ]
  },
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Delete a secret

**delete** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets/{secret_id}`

Deletes a single secret

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

- `secret_id: string`

  Secret identifier tag.

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional unknown`

  Result is null for delete operations.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID \
    -X DELETE \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {}
}
```

## Delete secrets

**delete** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets`

Deletes one or more secrets

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional unknown`

  Result is null for delete operations.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets \
    -X DELETE \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {}
}
```

## Duplicate Secret

**post** `/accounts/{account_id}/secrets_store/stores/{store_id}/secrets/{secret_id}/duplicate`

Duplicates the secret, keeping the value

### Path Parameters

- `account_id: string`

  Account Identifier

- `store_id: string`

  Store Identifier

- `secret_id: string`

  Secret identifier tag.

### Body Parameters

- `name: string`

  The name of the secret

- `scopes: array of string`

  The list of services that can use this secret.

- `comment: optional string`

  Freeform text describing the secret

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets/$SECRET_ID/duplicate \
    -H 'Content-Type: application/json' \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -d '{
          "name": "MY_API_KEY",
          "scopes": [
            "workers",
            "ai_gateway",
            "dex",
            "access"
          ],
          "comment": "info about my secret"
        }'
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {
    "id": "3fd85f74b32742f1bff64a85009dda07",
    "created": "2023-09-21T18:56:32.624632Z",
    "modified": "2023-09-21T18:56:32.624632Z",
    "name": "MY_API_KEY",
    "status": "pending",
    "store_id": "023e105f4ecef8ad9ca31a8372d0c353",
    "comment": "info about my secret",
    "scopes": [
      "workers",
      "ai_gateway",
      "dex",
      "access"
    ]
  },
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Domain Types

### Secret List Response

- `SecretListResponse object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

### Secret Get Response

- `SecretGetResponse object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

### Secret Create Response

- `SecretCreateResponse object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

### Secret Edit Response

- `SecretEditResponse object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

### Secret Delete Response

- `SecretDeleteResponse = unknown`

  Result is null for delete operations.

### Secret Bulk Delete Response

- `SecretBulkDeleteResponse = unknown`

  Result is null for delete operations.

### Secret Duplicate Response

- `SecretDuplicateResponse object { id, created, modified, 5 more }`

  - `id: string`

    Secret identifier tag.

  - `created: string`

    Whenthe secret was created.

  - `modified: string`

    When the secret was modified.

  - `name: string`

    The name of the secret

  - `status: "pending" or "active" or "deleted"`

    - `"pending"`

    - `"active"`

    - `"deleted"`

  - `store_id: string`

    Store Identifier

  - `comment: optional string`

    Freeform text describing the secret

  - `scopes: optional array of string`

    The list of services that can use this secret.

# Quota

## View secret usage

**get** `/accounts/{account_id}/secrets_store/quota`

Lists the number of secrets used in the account.

### Path Parameters

- `account_id: string`

  Account Identifier

### Returns

- `errors: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `messages: array of object { code, message, documentation_url, source }`

  - `code: number`

  - `message: string`

  - `documentation_url: optional string`

  - `source: optional object { pointer }`

    - `pointer: optional string`

- `success: true`

  Whether the API call was successful.

  - `true`

- `result: optional object { secrets }`

  - `secrets: object { quota, usage }`

    - `quota: number`

      The number of secrets the account is entitlted to use

    - `usage: number`

      The number of secrets the account is currently using

- `result_info: optional object { count, page, per_page, 2 more }`

  - `count: optional number`

    Total number of results for the requested service.

  - `page: optional number`

    Current page within paginated list of results.

  - `per_page: optional number`

    Number of results per page of results.

  - `total_count: optional number`

    Total results available without any search parameters.

  - `total_pages: optional number`

    The number of total pages in the entire result set.

### Example

```http
curl https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/quota \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY"
```

#### Response

```json
{
  "errors": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "messages": [
    {
      "code": 1000,
      "message": "message",
      "documentation_url": "documentation_url",
      "source": {
        "pointer": "pointer"
      }
    }
  ],
  "success": true,
  "result": {
    "secrets": {
      "quota": 10,
      "usage": 10
    }
  },
  "result_info": {
    "count": 1,
    "page": 1,
    "per_page": 20,
    "total_count": 2000,
    "total_pages": 100
  }
}
```

## Domain Types

### Quota Get Response

- `QuotaGetResponse object { secrets }`

  - `secrets: object { quota, usage }`

    - `quota: number`

      The number of secrets the account is entitlted to use

    - `usage: number`

      The number of secrets the account is currently using

---

---
title: BYOK (Store Keys)
description: Securely store AI provider API keys in AI Gateway and reference them in your gateway configuration.
image: https://developers.cloudflare.com/dev-products-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/ai-gateway/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# BYOK (Store Keys)

## Introduction

Bring your own keys (BYOK) is a feature in Cloudflare AI Gateway that allows you to securely store your AI provider API keys directly in the Cloudflare dashboard. Instead of including API keys in every request to your AI models, you can configure them once in the dashboard, and reference them in your gateway configuration.

The keys are stored securely with [Secrets Store](https://developers.cloudflare.com/secrets-store/) and allows for:

* Secure storage and limit exposure
* Easier key rotation
* Rate limit, budget limit and other restrictions with [Dynamic Routes](https://developers.cloudflare.com/ai-gateway/features/dynamic-routing/)

## Setting up BYOK

### Prerequisites

* Ensure your gateway is [authenticated](https://developers.cloudflare.com/ai-gateway/configuration/authentication/).
* Ensure you have appropriate [permissions](https://developers.cloudflare.com/secrets-store/access-control/) to create and deploy secrets on Secrets Store.

### Configure API keys

1. Log into the [Cloudflare dashboard ↗](https://dash.cloudflare.com/) and select your account.
2. Go to **AI** \> **AI Gateway**.
3. Select your gateway or create a new one.
4. Go to the **Provider Keys** section.
5. Click **Add API Key**.
6. Select your AI provider from the dropdown.
7. Enter your API key and optionally provide a description.
8. Click **Save**.

### Update your applications

Once you've configured your API keys in the dashboard:

1. **Remove API keys from your code**: Delete any hardcoded API keys or environment variables.
2. **Update request headers**: Remove provider authorization headers from your requests. Note that you still need to pass `cf-aig-authorization`.
3. **Test your integration**: Verify that requests work without including API keys.

## Example

With BYOK enabled, your workflow changes from:

1. **Traditional approach**: Include API key in every request header  
Terminal window  
```  
curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions \  
  -H 'cf-aig-authorization: Bearer {CF_AIG_TOKEN}' \  
  -H "Authorization: Bearer YOUR_OPENAI_API_KEY" \  
  -H "Content-Type: application/json" \  
  -d '{"model": "gpt-4", "messages": [...]}'  
```
2. **BYOK approach**: Configure key once in dashboard, make requests without exposing keys  
Terminal window  
```  
curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions \  
  -H 'cf-aig-authorization: Bearer {CF_AIG_TOKEN}' \  
  -H "Content-Type: application/json" \  
  -d '{"model": "gpt-4", "messages": [...]}'  
```

## Managing API keys

### Viewing configured keys

In the AI Gateway dashboard, you can:

* View all configured API keys by provider
* See when each key was last used
* Check the status of each key (active, expired, invalid)

### Rotating keys

To rotate an API key:

1. Generate a new API key from your AI provider
2. In the Cloudflare dashboard, edit the existing key entry
3. Replace the old key with the new one
4. Save the changes

Your applications will immediately start using the new key without any code changes or downtime.

### Revoking access

To remove an API key:

1. In the AI Gateway dashboard, find the key you want to remove
2. Click the **Delete** button
3. Confirm the deletion

Impact of key deletion

Deleting an API key will immediately stop all requests that depend on it. Make sure to update your applications or configure alternative keys before deletion.

## Multiple keys per provider

AI Gateway supports storing multiple API keys for the same provider. This allows you to:

* Use different keys for different use cases (for example, development vs production)
* Gradually migrate between keys during rotation

### Key aliases

Each API key can be assigned an alias to identify it. When you add a key, you can specify a custom alias, or the system will use `default` as the alias.

When making requests, AI Gateway uses the key with the `default` alias by default. To use a different key, include the `cf-aig-byok-alias` header with the alias of the key you want to use.

### Example: Using a specific key alias

If you have multiple OpenAI keys configured with different aliases (for example, `default`, `production`, and `testing`), you can specify which one to use:

Terminal window

```

# Uses the key with alias "default" (no header needed)

curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions \

  -H 'cf-aig-authorization: Bearer {CF_AIG_TOKEN}' \

  -H "Content-Type: application/json" \

  -d '{"model": "gpt-4", "messages": [...]}'


```

Terminal window

```

# Uses the key with alias "production"

curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions \

  -H 'cf-aig-authorization: Bearer {CF_AIG_TOKEN}' \

  -H 'cf-aig-byok-alias: production' \

  -H "Content-Type: application/json" \

  -d '{"model": "gpt-4", "messages": [...]}'


```

Terminal window

```

# Uses the key with alias "testing"

curl https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions \

  -H 'cf-aig-authorization: Bearer {CF_AIG_TOKEN}' \

  -H 'cf-aig-byok-alias: testing' \

  -H "Content-Type: application/json" \

  -d '{"model": "gpt-4", "messages": [...]}'


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/ai-gateway/","name":"AI Gateway"}},{"@type":"ListItem","position":3,"item":{"@id":"/ai-gateway/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/ai-gateway/configuration/bring-your-own-keys/","name":"BYOK (Store Keys)"}}]}
```

---

---
title: Workers integration
description: Cloudflare Secrets Store is a secure, centralized location in which account-level secrets are stored and managed. The secrets are securely encrypted and stored across all Cloudflare data centers.
image: https://developers.cloudflare.com/core-services-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/secrets-store/llms.txt  
> Use this file to discover all available pages before exploring further.

[Skip to content](#%5Ftop) 

# Workers integration

[Cloudflare Secrets Store](https://developers.cloudflare.com/secrets-store/) is a secure, centralized location in which account-level secrets are stored and managed. The secrets are securely encrypted and stored across all Cloudflare data centers.

Consider the steps below to learn how to use values from your account secrets store with [Cloudflare Workers](https://developers.cloudflare.com/workers/).

Note

This is different from Workers [Variables and Secrets](https://developers.cloudflare.com/workers/configuration/secrets/), where you define and manage your secrets on a per-Worker level.

## Before you begin

* If [using the Dashboard](#via-dashboard), make sure you already have a Workers application. Refer to the [Workers get started](https://developers.cloudflare.com/workers/get-started/dashboard/) for guidance.
* You should also have a store created under the **Secrets Store** tab on the Dashboard. The first store in your account is created automatically when a user with [Super Administrator or Secrets Store Admin role](https://developers.cloudflare.com/secrets-store/access-control/) interacts with it.  
   * If no store exists in your account yet and you have the necessary permissions, you can use the [Wrangler command](https://developers.cloudflare.com/workers/wrangler/commands/secrets-store/#secrets-store-store) `secrets-store store create <name> --remote` to create your first store.

Local development mode

This guide assumes you are working in production. To use Secrets Store locally, you must use `secrets-store secret` [Wrangler commands](https://developers.cloudflare.com/workers/wrangler/commands/) without the `--remote` flag.

## 1\. Set up account secrets in Secrets Store

Follow the steps below to create secrets. You must have a [Super Administrator or a Secrets Store Admin role](https://developers.cloudflare.com/secrets-store/access-control/) within your Cloudflare account.

Note

You may also add account secrets directly from the Workers settings on the dashboard. You can skip to [step 2](#via-dashboard) to do that.

* [ Wrangler ](#tab-panel-8179)
* [ Dashboard ](#tab-panel-8180)
* [ API ](#tab-panel-8181)

Use the [Wrangler command](https://developers.cloudflare.com/workers/wrangler/commands/secrets-store/#secrets-store-secret) `secrets-store secret create`.

To use the following example, replace the store ID and secret name by your actual data. You can find and copy the store ID from the [Secrets Store tab ↗](https://dash.cloudflare.com/?to=/:account/secrets-store/) on the dashboard or use `wrangler secrets-store store list`.

Note that a secret name cannot contain spaces.

Terminal window

```

npx wrangler secrets-store secret create <STORE_ID> --name MY_SECRET_NAME --scopes workers --remote


```

```

✓ Enter a secret value: › ***


🔐 Creating secret... (Name: MY_SECRET_NAME, Value: REDACTED, Scopes: workers, Comment: undefined)

✓ Select an account: › My account

✅ Created secret! (ID: 13bc7498c6374a4e9d13be091c3c65f1)


```

1. In the Cloudflare dashboard, go to the **Secrets Store** page.  
[ Go to **Secrets Store** ](https://dash.cloudflare.com/?to=/:account/secrets-store)
2. Select **Create secret**.
3. Fill in the required fields, choosing _Workers_ as the **Permission scope**. Once the secret is saved, the secret value will no longer be available for viewing.
4. (Optional) Select **Add additional secret** to create more than one secret at a time.
5. Select **Save** to confirm.

You can find and copy the store ID from the [Secrets Store tab ↗](https://dash.cloudflare.com/?to=/:account/secrets-store/) on the dashboard or use the [Wrangler command](https://developers.cloudflare.com/workers/wrangler/commands/secrets-store/#secrets-store-store). Also, make sure your secret `name` does not contain spaces.

Refer to [Secrets Store API](https://developers.cloudflare.com/api/resources/secrets%5Fstore/) for the full API documentation.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Secrets Store Write`

Create a secret

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/secrets_store/stores/$STORE_ID/secrets" \

  --request POST \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY" \

  --json '[

    {

        "name": "<MY_SECRET_NAME>",

        "value": "<SECRET_VALUE>",

        "scopes": [

            "workers"

        ],

        "comment": ""

    },

    {

        "name": "<MY_SECRET_NAME_2>",

        "value": "<SECRET_VALUE>",

        "scopes": [

            "workers"

        ],

        "comment": ""

    }

  ]'


```

Refer to [manage account secrets](https://developers.cloudflare.com/secrets-store/manage-secrets/) for further options.

## 2\. Bind an account secret to your Worker

[Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) allow your Worker to interact with resources on your Cloudflare account.

To bind an account secret to your Worker, you must have one of the following [roles within your Cloudflare account](https://developers.cloudflare.com/secrets-store/access-control/):

* Super Administrator
* Secrets Store Deployer

### Via Wrangler

1. Add a Secrets Store binding to your [Wrangler configuration file](https://developers.cloudflare.com/workers/wrangler/configuration/):  
   * `binding`: a descriptive name for your binding. This will be used in the Workers application when [accessing your secret on the env object](https://developers.cloudflare.com/secrets-store/integrations/workers/#3-access-the-secret-on-the-env-object).  
   * `store_id`: the corresponding Secrets Store ID where your account secret was created.  
   * `secret_name`: the unique secret name, defined when your account secret was created.

* [  wrangler.jsonc ](#tab-panel-8177)
* [  wrangler.toml ](#tab-panel-8178)

JSONC

```

{

  "main": "./src/index.js",

  "secrets_store_secrets": [

    {

      "binding": "<BINDING_VARIABLE>",

      "store_id": "<STORE_ID>",

      "secret_name": "<MY_SECRET_NAME>"

    }

  ]

}


```

TOML

```

main = "./src/index.js"


[[secrets_store_secrets]]

binding = "<BINDING_VARIABLE>"

store_id = "<STORE_ID>"

secret_name = "<MY_SECRET_NAME>"


```

### Via Dashboard

1. In the Cloudflare dashboard, go to **Workers & Pages**.  
[ Go to **Workers & Pages** ](https://dash.cloudflare.com/?to=/:account/workers-and-pages)
2. Select a Workers application.
3. Go to **Settings** \> **Bindings** and select **Add**.
4. On the **Add a resource binding** side panel, choose **Secrets Store**.
5. Fill in the required fields:  
   * **Variable name**: a name for the binding. This will be used for your Worker to access the secret ([step 3](#3-access-the-secret-on-the-env-object) below).  
   * **Secret name**: select from the list of available account secrets created in [step 1](#1-set-up-account-secrets-in-secrets-store).  
   * (Optional - Admins only) If the secret you need does not exist yet, select **Create secret**. This will add an account level secret in the same way as if you had [created it on the Secrets Store](https://developers.cloudflare.com/secrets-store/manage-secrets/).
6. Select **Deploy** to deploy your binding. When deploying, there are two options:  
   * **Deploy:** Immediately deploy the binding to 100% of your audience.  
   * **Save version:** Save a version of the binding which you can deploy in the future.

## 3\. Access the secret on the `env` object

[Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/) are located on the `env` object. To access the secret you first need an asynchronous call.

### Call `get()` on the binding variable

Local development mode

You cannot access production secrets (created on the dashboard, via API, or with the `--remote` flag) from your local development setup. To use Secrets Store locally, you must use `secrets-store secret` [Wrangler commands](https://developers.cloudflare.com/workers/wrangler/commands/) without the `--remote` flag.

JavaScript

```

export default {

  async fetch(request, env) {

    // Example of using the secret safely in an API request

    const APIkey = await env.<BINDING_VARIABLE>.get()


    const response = await fetch("https://api.example.com/data", {

      headers: { "Authorization": `Bearer ${APIKey}` },

    });


    if (!response.ok) {

      return new Response("Failed to fetch data", { status: response.status });

    }


    const data = await response.json();

    return new Response(JSON.stringify(data), {

      headers: { "Content-Type": "application/json" },

    });

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/secrets-store/","name":"Secrets Store"}},{"@type":"ListItem","position":3,"item":{"@id":"/secrets-store/integrations/","name":"Secrets Store integrations"}},{"@type":"ListItem","position":4,"item":{"@id":"/secrets-store/integrations/workers/","name":"Workers integration"}}]}
```
