Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,10 @@ The console's own `/api` serves its web UI only and is not a public API.
Before 1.0 there is no compatibility promise: use the pairs above. The Usage page reads
light-tokenmeter's HTTP summary API, which stays compatible within its 1.x.

`scripts/e2e.sh` checks this on every pull request and daily: it builds KTMS and light-tokenmeter
from `main` (or `KTMS_REF` / `TOKENMETER_REF`), turns light-tokenmeter's authentication on, and
drives the console's API through models, rules, vendor keys, client keys, spend limits, tenants, a
playground call through a mock vendor and its usage report.
`scripts/e2e.sh` checks this on every pull request, against the KTMS and light-tokenmeter refs in
`scripts/e2e.refs`, and daily against their `main`: it turns light-tokenmeter's authentication on and
drives the console's API through models, rules, vendor keys, client keys and their policies, spend
limits and spend, tenants, a playground call through a mock vendor and its usage report.

## Running with one backend or both

Expand Down
31 changes: 28 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,44 @@
# Security policy

## Supported versions

| Version | Supported |
| ------- | --------- |
| `1.x`, latest minor release | :white_check_mark: |
| `0.x` | :x: upgrade to 1.0 |

## Reporting a vulnerability

Please do **not** open a public issue. Use GitHub's
[private vulnerability reporting](https://github.com/ai-process/ktms-admin/security/advisories/new)
for this repository. You will get a first answer within a few days.

## Verifying a release

From 1.0.0 on, images are signed with keyless [Sigstore cosign](https://docs.sigstore.dev/) and carry an
SBOM and SLSA provenance. Use cosign 3 and pin the identity to the tag you verify:

```bash
V=v1.0.0
cosign verify coyl/ktms-admin:${V#v} \
--certificate-identity "https://github.com/ai-process/ktms-admin/.github/workflows/docker-publish.yml@refs/tags/$V" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
docker buildx imagetools inspect coyl/ktms-admin:${V#v} --format '{{ json .SBOM }}'
```

## What this console protects

The console holds an **admin key for the KTMS gateway**, which can read and change routing and mint API
keys. Treat access to it accordingly:

- Only people matching `ALLOWED_EMAILS` (full access) or `VIEWER_EMAILS` (read-only) can sign in, and
only with a Google-verified address. The lists are re-checked on every request.
- Only verified e-mails that match `ALLOWED_EMAILS` (admins), `VIEWER_EMAILS` (read-only) or
`TEAM_MEMBERSHIPS` (one team's keys and spend) can sign in, and the lists are re-checked on every
request. Sign-in is a password (argon2id or bcrypt hashes, with back-off per account and client
address), OpenID Connect, GitHub, or an access proxy.
- An access proxy's e-mail header is trusted only from `TRUSTED_PROXY_CIDRS`; Cloudflare Access tokens
are verified against the team's keys. Never expose the console directly when relying on a header.
- The admin key never reaches the browser; vendor API keys are write-only through the console.
- Mutating requests need the admin role, a custom `X-Requested-With` header and a same-origin `Origin`.
- Mutating requests need a role allowed to make them, a custom `X-Requested-With` header and a
same-origin `Origin`.
- Run it behind HTTPS (`PUBLIC_URL=https://…`); cookies are then `Secure`, `HttpOnly` and `SameSite=Lax`.
- `INSECURE_NO_AUTH` disables sign-in and is refused unless `PUBLIC_URL` is localhost.
Loading