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

# Secrets and keys

> Where every secret lives, and how to add or rotate one.

No secret is in the repository, in Terraform state, or in a build log. CI scans every commit for secrets.

## Secrets Manager

| Secret | Holds | Made by |
| - | - | - |
| `oncoeverything/app` | A JSON object of third-party keys, listed below | Staff, by hand |
| `oncoeverything/auth-secret` | The key that signs session cookies | Staff, by hand |
| `oncoeverything/delivery-runner-key` | The key for the internal delivery routes | Terraform |
| `rds!db-…` | The database password | RDS, which rotates it |

The keys in `oncoeverything/app`:

| Key | Turns on |
| - | - |
| `CLOUDFRONT_PRIVATE_KEY` | Signed download links |
| `STRIPE_SECRET_KEY`, `STRIPE_WEBHOOK_SECRET` | Card payments |
| `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` | Google sign-in |

The API reads the secrets when a task starts.

## Add or change a key in the app secret

**1. Read the current secret and add the key**

This keeps the keys already there.

```bash theme={null}
export AWS_PROFILE=onco
aws secretsmanager get-secret-value --secret-id oncoeverything/app \
  --query SecretString --output text \
  | jq --arg value "<new value>" '.KEY_NAME = $value' > app-secret.json
```

**2. Write it back**

```bash theme={null}
aws secretsmanager put-secret-value --secret-id oncoeverything/app \
  --secret-string file://app-secret.json
```

**3. Delete the local file**

Delete `app-secret.json` immediately.

**4. Restart the API**

```bash theme={null}
aws ecs update-service --cluster oncoeverything \
  --service oncoeverything-api --force-new-deployment
```

## Rotate the session key

Write a new random value. Then restart the API. After the restart, every user must sign in again.

```bash theme={null}
aws secretsmanager put-secret-value --secret-id oncoeverything/auth-secret \
  --secret-string "$(openssl rand -base64 48)"
```

## Access without keys

* **People** sign in to AWS through SSO. Nobody has an AWS access key.
* **GitHub Actions** assumes a role through OIDC. The role can push API images, register task definitions, pass the API task its roles, and update the API service.
* **The API task** has a role that can read its own secrets, send email and use its two buckets.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.