feat: add /certify endpoint for verification key certificates - #65
Open
pointche-ens wants to merge 3 commits into
Open
feat: add /certify endpoint for verification key certificates#65pointche-ens wants to merge 3 commits into
pointche-ens wants to merge 3 commits into
Conversation
pointche-ens
requested review from
Manuthor and
charming-wicket-5502
and
a lite review from Copilot
August 25, 2026 08:21
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the authentication server’s API contract by introducing long-lived, ES256-signed verification-key certificates via a new session-cookie-authenticated POST /certify endpoint, plus a dedicated certificate JWKS discovery endpoint (GET /.well-known/certificate-jwks.json). It also removes the old public_key_pem login field/claim in favor of this new certificate flow.
Changes:
- Added
/certifyissuance +/.well-known/certificate-jwks.jsondiscovery, wired into the Actix app with a dedicated certificate signing key config. - Added per-realm
certificate_max_age_secondspersisted in DB backends and exposed in models/config/docs/OpenAPI. - Removed
public_key_pemfrom login request + removed the session private claim it populated; updated tests/docs/UI typings accordingly.
Reviewed changes
Copilot reviewed 40 out of 40 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| server/src/server/endpoints/client_endpoints.rs | Implements POST /certify and GET /.well-known/certificate-jwks.json; removes public_key_pem use during login. |
| server/src/server/auth_verifier.rs | Wires certificate JWT config + JWKS into app data and routes; adds /certify scope and well-known JWKS route. |
| server/src/server/parameters/server_params.rs | Adds certificate_jwt_params and helpers to load certificate signing keys. |
| server/src/server/parameters/auth_params.rs | Introduces CertificateJwtParams config struct. |
| server/src/server/parameters/mod.rs | Re-exports CertificateJwtParams. |
| server/src/server/endpoints/mod.rs | Exports new certify/JWKS handlers. |
| server/src/session/jwt.rs | Removes public_key_pem from session token issuance path and corresponding tests. |
| server/src/lib.rs | Re-exports CertificateClaims from the shared client crate. |
| server/src/server/dev_seed.rs | Seeds dev realm with certificate_max_age_seconds. |
| server/src/database/trait.rs | Updates default realm creation to include certificate_max_age_seconds. |
| server/src/database/tests.rs | Updates realm test fixtures for the new realm field. |
| server/src/database/impls/sqlite.rs | Adds certificate_max_age_seconds column + migration and includes it in CRUD queries. |
| server/src/database/impls/postgres.rs | Adds certificate_max_age_seconds column + migration and includes it in CRUD queries. |
| server/src/database/impls/mysql.rs | Adds certificate_max_age_seconds column + migration and includes it in CRUD queries. |
| server/documentation/openapi.yaml | Updates schema: removes public_key_pem, adds /certify, certificate JWKS, and certificate claims/DTOs. |
| server/documentation/docs/api_reference.md | Documents /certify and the certificate JWKS endpoint; updates login request/claims docs. |
| server/documentation/docs/client_library.md | Updates login examples and removes public_key_pem from documented claims. |
| server/auth_verifier.dev.toml | Documents and enables [certificate_jwt_params] in the dev config. |
| server/auth_verifier.spire.toml | Documents optional [certificate_jwt_params] for spire config. |
| pkg/auth_verifier.toml | Documents optional [certificate_jwt_params] for packaged config. |
| client/src/models/base.rs | Adds Realm::certificate_max_age_seconds with a one-year default. |
| client/src/models/mod.rs | Re-exports the new CertificateClaims model. |
| client/src/models/certificate_claims.rs | Adds the shared CertificateClaims payload model. |
| client/src/models/login.rs | Removes public_key_pem from LoginRequest. |
| client/src/models/client_claims.rs | Removes the as_pk private claim field. |
| client/src/lib.rs | Re-exports CertificateClaims. |
| client/src/client/auth_client.rs | Updates login client method signature to match new login body shape. |
| server/src/tests/certify_tests.rs | Adds integration tests for /certify issuance, auth requirement, error cases, JWKS availability, and key isolation. |
| server/src/tests/params.rs | Adds test params helper to configure certificate signing keys; adds dev TOML drift-guard test. |
| server/src/tests/mod.rs | Registers new certify_tests module and exports certify-capable params helper. |
| server/src/tests/username_password_tests.rs | Updates login calls and realm fixtures for new params/field. |
| server/src/tests/totp_tests.rs | Updates login calls for new signature and request body shape. |
| server/src/tests/jwt_tests.rs | Updates login calls and login request body shape; updates realm fixtures. |
| server/src/tests/cookie_auth_tests.rs | Updates login calls for new signature. |
| server/src/tests/helpers.rs | Updates login helpers and test realm fixtures with new realm field. |
| server/src/tests/sessions_api.rs | Updates login calls for new signature. |
| server/src/tests/sessions_store.rs | Updates realm fixtures with new realm field. |
| server/src/tests/admin_api.rs | Updates login calls and realm fixtures with new realm field. |
| admin-ui/src/types/api.ts | Removes public_key_pem from the UI-side LoginRequest type. |
| CHANGELOG/feat_certify.md | Adds changelog entry describing the new endpoints/params and the login claim removal. |
Suppressed comments (1)
client/src/client/auth_client.rs:364
- The PR adds
POST /certifyand a newCertificateClaimsmodel, but the Rust client library (AuthClient) doesn't expose a typed helper for calling/certify(nor request/response DTOs). Given this repo's pattern of keepingclient/andopenapi.yamlin sync, this leaves API consumers without first-class support.
// User API
impl AuthClient {
/// Call to the /login? realm={realm} endpoint to attempt authenticating the user
/// and return the authenticated user information and cookie if successful.
///
/// Pass `totp_code` when the server previously returned `TotpRequired` as the next step.
pub async fn login(
&self,
realm: &str,
totp_code: Option<String>,
) -> AuthResult<(AuthenticationResult, Option<Cookie<'_>>)> {
let user = self
.post::<LoginRequest, AuthenticationResult>(
&format!("/login?realm={}", realm),
&LoginRequest { totp_code },
)
.await?;
let cookie = self.get_cookie(&self.base_url)?;
Ok((user, cookie))
}
/// Call to the /whoami endpoint to get the authenticated user's claims
pub async fn whoami(&self, realm: &str) -> AuthResult<ClientClaims> {
self.get(&format!("/whoami?realm={}", realm)).await
}
/// Call to the /public/version endpoint to retrieve the server version string.
pub async fn get_version(&self) -> AuthResult<String> {
let v: Version = self.get("/public/version").await?;
Ok(v.version)
}
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
pointche-ens
force-pushed
the
feat/certify
branch
from
August 25, 2026 16:50
1cc3e70 to
c2f56d1
Compare
Manuthor
reviewed
Aug 25, 2026
pointche-ens
force-pushed
the
feat/certify
branch
from
August 25, 2026 19:02
c2f56d1 to
9a95484
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
POST /certify, a session-cookie-authenticated endpoint that certifies acaller-supplied verification key under the caller's own
realm_id/sub/auth_scheme,returning a long-lived, ES256-signed certificate. Signed with a dedicated certificate
signing key (
certificate_jwt_params), entirely separate from the session JWT key, so acertificate can never be presented back as a session cookie/token.
GET /.well-known/certificate-jwks.jsonfor discovering the certificate signingpublic key — a separate document from the existing session
/.well-known/jwks.json.certificate_max_age_seconds(defaults to one year) controllingcertificate validity.
[certificate_jwt_params]inauth_verifier.dev.toml,pkg/auth_verifier.toml,and
auth_verifier.spire.toml.public_key_pemfromPOST /loginand theas_pkclaim it populated, as itsrole has been replaced by
/certify.