> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sailresearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Credential injection

> Let a Sailbox call authenticated HTTPS APIs without storing credentials inside it

Use credential injection when code in a Sailbox needs to call an HTTPS API
with an API key or token. Store the credential as a secret for your
organization, then attach an HTTP policy that adds it to matching requests.

Your code sends a normal request without the credential, and Sail adds the
credential before sending the request to the matched API. Sail's secret APIs
never return a stored value.

## Set up credential injection

This example stores a GitHub token, creates a policy for `api.github.com`, and
attaches the policy to an existing Sailbox. The policy adds the token to the
`authorization` header on HTTPS requests to that host.

In the CLI example, replace the example Sailbox and policy IDs with your own.
`sail box list` shows your Sailbox IDs, and the create command prints the new
policy ID. In the SDK examples, `sailbox` refers to a Sailbox you created
earlier.

<CodeGroup>
  ```bash CLI theme={null}
  # Enter the token at the hidden prompt.
  sail secret set GITHUB_TOKEN

  cat > github-policy.json <<'JSON'
  {
    "api.github.com": {
      "rules": [
        {
          "request": {
            "set": {
              "headers": {
                "authorization": "Bearer ${secrets.GITHUB_TOKEN}"
              }
            }
          }
        }
      ]
    }
  }
  JSON

  sail http-policy create github --file github-policy.json
  sail box http-policy set sb_abc123 hp_abc123
  ```

  ```python Python theme={null}
  import os

  import sail

  sail.Secret.set("GITHUB_TOKEN", os.environ["GITHUB_TOKEN"])

  policy = sail.HttpPolicy.create(
      "github",
      {
          "api.github.com": {
              "rules": [
                  {
                      "request": {
                          "set": {
                              "headers": {
                                  "authorization": "Bearer ${secrets.GITHUB_TOKEN}",
                              },
                          },
                      },
                  },
              ],
          },
      },
  )

  sailbox.set_http_policy(policy)
  ```

  ```typescript TypeScript theme={null}
  import { HttpPolicy, Secret } from "@sailresearch/sdk";

  await Secret.set("GITHUB_TOKEN", process.env.GITHUB_TOKEN!);

  const policy = await HttpPolicy.create("github", {
    "api.github.com": {
      rules: [
        {
          request: {
            set: {
              headers: {
                authorization: "Bearer ${secrets.GITHUB_TOKEN}",
              },
            },
          },
        },
      ],
    },
  });

  await sailbox.setHttpPolicy(policy);
  ```

  ```rust Rust theme={null}
  use sail::Client;
  use serde_json::json;

  let client = Client::from_env()?;

  client
      .set_secret("GITHUB_TOKEN", &std::env::var("GITHUB_TOKEN")?)
      .await?;

  let policy = client
      .create_http_policy(
          "github",
          &json!({
              "api.github.com": {
                  "rules": [
                      {
                          "request": {
                              "set": {
                                  "headers": {
                                      "authorization": "Bearer ${secrets.GITHUB_TOKEN}",
                                  },
                              },
                          },
                      },
                  ],
              },
          }),
      )
      .await?;

  sailbox.set_http_policy(&policy).await?;
  ```
</CodeGroup>

The secret and policy belong to your organization. You can attach the same
policy to more than one Sailbox. Each Sailbox can have one policy attached at a
time.

## Choose which requests receive a credential

The rules in a policy are grouped by hostname. Write only the hostname, such as
`api.github.com`. Do not include `https://`, a port, or a path.

You can use a wildcard like `*.example.com` or the catch-all `*` as a host, but
prefer a plain hostname where possible. A wildcard such as `*.example.com`
sends the credential to every matching direct subdomain. Use a wildcard only
when you trust every matching host.

The example has no `match` field, so its rule covers every request to
`api.github.com`. You can add a `match` field to limit a rule by request method,
path, headers, or query parameters. See [HTTP policies](/sailboxes-http-policies)
for more rule examples and options.

Credential injection works only for HTTPS requests. Plain HTTP and raw TCP
connections are unchanged, and so is a connection from a rare HTTPS client
that does not announce its HTTP version while connecting; the
[limitations in HTTP policies](/sailboxes-http-policies#limitations) section shows
how you can handle this case.

## Use a stored secret

Write `${secrets.NAME}` where a stored value should appear. In the example,
`${secrets.GITHUB_TOKEN}` refers to the organization secret named
`GITHUB_TOKEN`.

A policy can insert a secret inside `request.set.headers` or
`request.set.query`.

Secret names start with a letter or number, can contain letters, numbers,
underscores, and dashes, and can be up to 128 characters. A value cannot be
empty, can be up to 64 KiB, and must be one line of text: no ASCII control
characters such as tabs or line breaks.

Get and list calls return a secret's name and timestamps, never its value. If
you set the same name again, Sail updates that organization secret. After the
update call succeeds, the next matching request from any Sailbox whose
attached policy uses it gets the new value.

## Replace or clear a policy

Attaching a policy replaces the policy currently attached to that Sailbox,
and clearing it leaves the Sailbox with no policy. The change affects HTTPS
connections the Sailbox opens after the call succeeds; a connection that is
already open keeps the previous policy until it closes.

Policy documents cannot change after creation. To change the rules, create a
new policy and attach it. [HTTP policies](/sailboxes-http-policies) covers
attachment in detail.

## Delete policies and secrets

You cannot delete a policy while it is attached to a Sailbox. You also cannot
delete a secret while any policy refers to it. Delete resources in this order:

1. Clear or replace the policy on every Sailbox that uses it.
2. Delete every policy that refers to the secret.
3. Delete the secret.

`sail http-policy list` shows how many Sailboxes use each policy and which
secret names it refers to.

For forwarding, policy-generated responses, and other request changes, see
[HTTP policies](/sailboxes-http-policies).
