Skip to content

feat(pg-pkg): add /v2/api-key/validate endpoint - #167

Merged
rubenhensen merged 1 commit into
mainfrom
feat/api-key-validate-endpoint
May 6, 2026
Merged

feat(pg-pkg): add /v2/api-key/validate endpoint#167
rubenhensen merged 1 commit into
mainfrom
feat/api-key-validate-endpoint

Conversation

@rubenhensen

@rubenhensen rubenhensen commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds GET /v2/api-key/validate so sibling services can confirm a PG-… API key is valid and read the tenant id without going through signing-key issuance. Pairs with encryption4all/cryptify#139, which switches cryptify's quota-tier check from a parallel hashed allowlist to this endpoint.

What changed

  • New handler pg-pkg/src/handlers/api_key_validate.rs. Pulls the validated ApiKeyData out of request extensions, returns { tenant_id, organisation_name }. tenant_id is organizations.id (uuid, stringified).
  • ApiKeyData gains an org_id: String field; PgApiKeyStore::lookup now selects o.id::text from the JOIN.
  • Auth middleware inserts ApiKeyData into request extensions (alongside the existing ApiKeySigningInfo) so the new handler can read identity without re-querying.
  • Route is wired under the /v2 scope, gated on ApiKeyGuard + Auth::new(_, AuthType::Key).with_db_pool(...). Only registered when a database pool is configured (same gate as /sign/key).

Tests

4 new unit tests on setup_api_key_validate_test:

  • success → 200 with tenant_id and organisation_name from the mock store
  • unknown key → middleware rejects (no 200)
  • missing Authorization → 404 (guard fails, no matching route)
  • non-PG bearer (e.g. JWT) → 404 (guard fails, falls through)

cargo test -p pg-pkg30 passed; 0 failed. cargo fmt --check clean.

Test plan

  • CI green (fmt, clippy, test)
  • Manual smoke against a running pg-pkg + business DB: curl -H 'Authorization: Bearer PG-<real-key>' http://pkg/v2/api-key/validate returns 200 + tenant id; with a bogus key returns 401; without the header returns 404
  • Confirm no regression on /v2/sign/key API-key auth path (existing 5 tests in test_api_key_signing_* cover this)

Deploy notes

Deploy this before the cryptify counterpart (encryption4all/cryptify#139) so cryptify's calls don't all hit the 30 s retry budget.

Sibling services (cryptify) need to confirm a `PG-…` API key is valid and
read the tenant id without going through signing-key issuance. Previously
they had to either re-implement the `business_api_keys` lookup against the
business database, or maintain a parallel allowlist of hashes — both create
drift on key rotation/revocation.

The new `GET /v2/api-key/validate` reuses the existing `Auth` middleware
with `AuthType::Key` and the `ApiKeyGuard`, returning
`{ tenant_id, organisation_name }` on success. `tenant_id` is
`organizations.id` (uuid, stringified) — added as a new field on
`ApiKeyData` and selected by `PgApiKeyStore::lookup`.

The route is only registered when a database pool is configured (same gate
as `/sign/key`), since validation has nothing to validate against without
the business schema.

Tests: success path returns the tenant id, unknown key is rejected, missing
or non-PG bearer 404s through the guard. All 30 pg-pkg tests pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant