# Request policies (https://tenki.cloud/docs/secrets/request-policies)

> For the complete documentation index, see [llms.txt](https://tenki.cloud/llms.txt)

Choose which outgoing HTTPS requests can use your saved secrets.

Your application sends a placeholder such as `secrets://GITHUB_TOKEN`. Tenki replaces it with the token only in outgoing HTTPS requests allowed by a policy.

| Item        | Example                  | Purpose                                                  |
| ----------- | ------------------------ | -------------------------------------------------------- |
| Secret      | `GITHUB_TOKEN`           | Stores the credential in your workspace.                 |
| Policy      | `github`                 | Defines which requests may use that credential.          |
| Placeholder | `secrets://GITHUB_TOKEN` | Tells Tenki which secret to substitute into the request. |

The placeholder always uses the **secret's name**. The policy has its own name because you can reuse one policy across sandboxes or let it permit several secrets.

You create secrets and policies separately. Each sandbox selects the policies it needs when it starts. Creating a policy alone gives no sandbox access to it.

## Create a policy

First [save a GitHub token as `GITHUB_TOKEN`](https://tenki.cloud/docs/secrets/manage-secrets.md#create-a-secret). Then create `github-policy.json`:

```json
[
  {
    "origin": "https://api.github.com",
    "methods": ["GET"],
    "pathPrefix": "/user",
    "header": "Authorization",
    "secrets": ["GITHUB_TOKEN"]
  }
]
```

Save it in your workspace:

```bash
tenki secrets policies create github --file ./github-policy.json
```

This permits `GITHUB_TOKEN` in the `Authorization` header of GET requests to `api.github.com` whose path begins with `/user`. Paths match by prefix, so this also includes paths such as `/user/repos`.

The JSON file contains permissions, not the token. It is safe to keep with your application configuration.

The policy is now ready to [select when starting a sandbox](https://tenki.cloud/docs/sandbox/secrets.md#call-an-api-with-transparent-injection). Policies control secret replacement, not all network traffic. They do not override the sandbox's network restrictions.

## Rule fields

A policy is an array of rules. Every rule specifies a destination, permitted methods, a path prefix, a location within the request, and the secrets allowed at that location.

| Field            | Meaning                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `origin`         | An HTTPS origin such as `https://api.example.com`. Use an exact hostname, without a path, wildcard, or explicit port.     |
| `methods`        | Allowed uppercase HTTP methods, such as `["GET", "POST"]`.                                                                |
| `pathPrefix`     | The beginning of the URL path. `/v1/` permits paths below `/v1/`. This is a literal prefix, not an exact-path match.      |
| `header`         | The header whose value may contain a placeholder, such as `Authorization`.                                                |
| `queryParameter` | An alternative to `header`: the query parameter whose value may contain a placeholder.                                    |
| `jsonPointer`    | An alternative to `header`: the JSON string location whose value may contain a placeholder, such as `/credentials/token`. |
| `secrets`        | Names of the stored secrets permitted at that location.                                                                   |

Specify exactly one of `header`, `queryParameter`, or `jsonPointer` per rule. Use separate rules to permit multiple locations.

Putting two names in `secrets` allows either secret to be referenced. It does not insert both values or choose one automatically. A rule only replaces a placeholder already present in the request; it does not add missing headers or fields.

### Query parameters and JSON bodies

For a service that accepts a credential in a query parameter or JSON body, the following policy illustrates both locations. Replace `api.example.com` with your service's hostname and create the `SERVICE_TOKEN` secret first.

```json
[
  {
    "origin": "https://api.example.com",
    "methods": ["GET"],
    "pathPrefix": "/v1/",
    "queryParameter": "api_key",
    "secrets": ["SERVICE_TOKEN"]
  },
  {
    "origin": "https://api.example.com",
    "methods": ["POST"],
    "pathPrefix": "/v1/",
    "jsonPointer": "/credentials/token",
    "secrets": ["SERVICE_TOKEN"]
  }
]
```

Your application can send `?api_key=secrets://SERVICE_TOKEN`, or this JSON body with `Content-Type: application/json`:

```json
{
  "credentials": {
    "token": "secrets://SERVICE_TOKEN"
  }
}
```

JSON pointers use `/` to separate object keys or array indexes. Escape a literal `~` as `~0` and a literal `/` as `~1` in a key. The selected value must be a string.

Use header authentication when your provider supports it. Query strings can appear in the destination's access logs. JSON injection supports uncompressed JSON bodies up to 256 KiB; malformed JSON, duplicate keys, or ambiguous referenced query parameters are rejected.

## List and inspect policies

```bash
tenki secrets policies list
tenki secrets policies get github
```

These commands show rules and metadata, never secret values. In the dashboard, use **Secrets → Policies**.

## Edit or delete a policy

Edit the local JSON file, then save the change:

```bash
tenki secrets policies update github --file ./github-policy.json
```

Changes apply to subsequent requests from sandboxes that selected this policy. Editing only the local file has no effect.

To remove that policy's permission:

```bash
tenki secrets policies delete github
```

Another selected policy can still authorize a matching request. In an interactive terminal, policy update and delete commands fetch the current revision. Scripts must supply `--revision` from `secrets policies get`.

Deleting and recreating a policy with the same name does not reconnect existing sandboxes to it. Start a new sandbox to select the replacement policy.