From 07688c9d386db468c7ad56558f55cc0dd9df89fc Mon Sep 17 00:00:00 2001 From: Vasil Date: Fri, 23 Oct 2026 19:22:32 +0200 Subject: [PATCH] docs: SECURITY.md for 1.0 (versions, verifying images, every sign-in method); e2e refs in README --- README.md | 8 ++++---- SECURITY.md | 31 ++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0e12eb1..ec633e7 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/SECURITY.md b/SECURITY.md index b139c7d..5752e1a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -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.