# Security Policy

`mgf-auth` is a federation sibling of [`mgf-common`](https://codeberg.org/magogi-admin/mgf-common),
shipping ISP-split auth verifier seams (a generic `SessionVerifier` +
`WebhookVerifier`, a Clerk adapter for session-JWT + Svix-webhook
verification, typed 401 errors, and test mocks). A vulnerability here
may affect every consumer that uses this library for authentication,
so we take security reports seriously.

## Supported versions

In the 0.x window, **only the latest MINOR receives security
patches.** Per [SemVer 0.x](https://semver.org/#spec-item-4) and
rule **AP-03** from `mgf-standard/docs/standards/API_DESIGN.md`,
each MINOR release MAY break the public API; we do not
branch-and-backport across minors.

| Version | Supported |
|---------|-----------|
| `0.1.x`  | ✅ — latest MINOR; security patches ship as `0.1.Y` |

## Reporting a vulnerability

**Please do not open a public issue or pull request** until we have
had a chance to triage and patch.

- **Email:** `bassam@magogi.org` with subject prefix
  `[mgf-auth security]`.
- **Codeberg private security advisory:** open a private
  vulnerability report at
  [the repository's Security tab](https://codeberg.org/magogi-admin/mgf-auth/security).

### What to include

- A description of the vulnerability and its impact.
- Steps to reproduce — a minimal failing test is ideal.
  For session-JWT or webhook-signature issues, the exact token /
  signed payload that bypassed verification matters.
- The version(s) of `mgf-auth`, `mgf-common`, and `pyjwt`
  affected.
- Python version + OS (if applicable).

### What to expect

| Stage | Timeline |
|---|---|
| Acknowledgement | within 3 business days |
| Initial assessment + severity rating | within 7 business days |
| Patch + release | within 30 days for high-severity, 90 days for medium |
| Credit + public disclosure | coordinated with the reporter |

90-day default embargo. After expiry (or after a patch ships),
the vulnerability is disclosed in the [`CHANGELOG.md`](CHANGELOG.md)
entry for the fixing release.

## Scope

**In scope:**

- Code in `src/mgf/auth/` (the published `mgf-auth` package).
  Specifically: the session-JWT verification in
  `mgf.auth.clerk_session` and the Svix-Signature HMAC webhook
  verification in `mgf.auth.clerk_webhook` (the HMAC-SHA256
  comparison over `<id>.<ts>.<body>` is the load-bearing
  security boundary — constant-time comparison and timestamp
  validation prevent signature-forgery and replay attacks).
- Build / release infrastructure (`pyproject.toml`, the manual
  release flow specified in
  [`mgf-standard/docs/standards/RELEASING.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/RELEASING.md)).

**Out of scope:**

- Vulnerabilities in `mgf-common` itself — report to
  [`mgf-common/SECURITY.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/SECURITY.md).
- Vulnerabilities in `pyjwt`, `cryptography`, or other
  transitive deps — report to the upstream project.
- Consumer-side identity-resolution bugs (the
  `principal_resolver` mapping Clerk ids to your principal) or
  session-revocation policy (the `revoked_sessions` table is a
  consumer concern) — that's application logic, not library
  scope.

## Hardening recommendations for consumers

Consumers of `mgf-auth` adopt the
[`mgf-standard/docs/standards/SECURITY_STANDARD.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/SECURITY_STANDARD.md)
engineering standard as their baseline.

Particular attention paid to:
- **Session revocation.** `SessionVerifier` verifies the
  JWT's signature and claims, but it does NOT check a
  `revoked_sessions` table — revocation is DB-coupled and
  app-specific, so it stays in the consumer. A consumer that
  needs immediate revocation MUST gate verified sessions through
  its own revocation check (a `RevocationGate`).
- **Webhook secret hygiene.** Treat the `webhook_secret`
  (`whsec_...`) like any other credential — never log it, never
  commit it, rotate it on suspected exposure. The HMAC
  verification is only as strong as the secret's secrecy.
- **Issuer + audience pinning.** Configure
  `ClerkSessionVerifier` with the exact `issuer` for your Clerk
  instance; an unpinned issuer accepts tokens minted by any
  Clerk tenant.

## A note on the standards

`mgf-auth` is a **federation sibling** under the
project-shape taxonomy from
[`mgf-standard/docs/standards/DOCUMENTATION.md`](https://codeberg.org/magogi-admin/mgf_common/src/branch/main/docs/standards/DOCUMENTATION.md) §2.0.
The cross-project engineering standards live in `mgf-common`;
this project inherits them. See
[`docs/standards/README.md`](docs/standards/README.md) for the
pointer.
