Service layer¶
The HTTP surface: the request and response envelope, bearer token verification, the single operation endpoint, and the ASGI application itself.
Request and response models¶
models
¶
Pydantic data models for the Cryptography Manager API.
These models are the single source of truth for the request envelope, the response envelope and the audit record. They deliberately avoid importing any cryptographic backend so that the schema stays importable even when optional extras such as PyDP, Pyfhel or MPyC are not installed.
Operation
¶
Bases: str, Enum
Cryptographic operation requested by the caller.
Backend
¶
Bases: str, Enum
Cryptographic library used to service an operation.
OutputFormat
¶
Bases: str, Enum
Desired response encoding.
JSON-LD is a plausible future addition, but its vocabulary would have to align with the Compliance Manager's DPV graphs, which are not pinned down yet. Only JSON is accepted for now; requesting anything else is a validation error rather than a silently ignored field.
DPQueryType
¶
Bases: str, Enum
Aggregate queries supported by the differential privacy adapter.
Mirrors the PyDP Laplacian algorithms wired up in the DP adapter. Declared here rather than imported from the adapter so that importing the schema never requires PyDP to be installed.
CryptographyRequest
¶
Bases: BaseModel
Request envelope for POST /cryptography.
The Authorization header is not modelled here; it is handled by the
auth dependency before the body is ever parsed.
check_backend_compatible
¶
Verify the requested backend can service the operation.
Returns:
| Type | Description |
|---|---|
str | None
|
An error message if the pairing is invalid, otherwise |
Source code in src/cryptography_manager/api/models.py
DPParameters
¶
Bases: BaseModel
Differential privacy parameters carried in parameters.
Validated separately from the envelope because the required fields depend
on the operation. epsilon_cost is the privacy price of the query and is
checked against the caller's remaining budget before execution.
CryptographyResponse
¶
Bases: BaseModel
Response envelope for POST /cryptography.
AuditRecord
¶
Bases: BaseModel
Structured audit entry produced for every request.
Sensitive material -- secret and private keys, plaintext values, secret
shares and intermediate cryptographic state -- must never reach this model.
Sanitisation happens in core.audit before construction.
Authentication¶
auth
¶
Bearer token verification.
Verification sits behind a small interface with two implementations, because the identity provider this component will ultimately talk to is not settled. The OIDC verifier targets the standard discovery and JWKS endpoints rather than any one vendor's API, so it should work against any conforming provider and needs replacing only if the eventual choice is non-standard.
The development verifier exists so the service is runnable with no identity provider at all. It still rejects a missing or malformed token, so the rejection path is exercised the same way in both modes -- it simply does not verify signatures, and must never be used outside development.
AuthResult
¶
AuthResult(
user_id: str | None = None,
claims: dict[str, Any] | None = None,
error: str | None = None,
)
Outcome of verifying a token.
Source code in src/cryptography_manager/api/auth.py
TokenVerifier
¶
Bases: Protocol
Verifies a bearer token and identifies the caller.
verify
¶
verify(token: str | None) -> AuthResult
Verify a token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str | None
|
The bearer token, without its scheme prefix. |
required |
Returns:
| Type | Description |
|---|---|
AuthResult
|
The verification outcome. Failures are returned rather than |
AuthResult
|
raised, because a rejected request still has to be audited. |
Source code in src/cryptography_manager/api/auth.py
DevTokenVerifier
¶
Accepts any well-formed token without verifying its signature.
Intended solely for development against no identity provider. It reads the claims of a JWT to identify the caller, and otherwise treats the token string itself as the identity.
verify
¶
verify(token: str | None) -> AuthResult
Identify the caller without cryptographic verification.
Source code in src/cryptography_manager/api/auth.py
OIDCTokenVerifier
¶
OIDCTokenVerifier(settings: Settings)
Verifies tokens against an OpenID Connect provider.
Keys are discovered through the provider's well-known configuration and cached by the JWKS client, so steady-state verification is local and does not add a network round trip per request.
Initialise the verifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings
|
Runtime settings carrying the issuer and client details. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no issuer is configured. |
Source code in src/cryptography_manager/api/auth.py
verify
¶
verify(token: str | None) -> AuthResult
Verify a token's signature, expiry and issuer.
Source code in src/cryptography_manager/api/auth.py
build_verifier
¶
build_verifier(settings: Settings) -> TokenVerifier
Construct the verifier selected by configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings
|
Runtime settings. |
required |
Returns:
| Type | Description |
|---|---|
TokenVerifier
|
The configured verifier. |
Source code in src/cryptography_manager/api/auth.py
extract_bearer
¶
Pull the token out of an Authorization header.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
header
|
str | None
|
Raw header value, if present. |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The token, or |
Source code in src/cryptography_manager/api/auth.py
Routes¶
routes
¶
HTTP routes.
The request body is read and validated inside the handler rather than through a typed signature. That is deliberate: the framework would otherwise consume and parse the body before the handler runs, which would bypass the audit trail, answer an unauthenticated caller with a schema complaint instead of a refusal, and buffer an arbitrarily large payload before anyone had a chance to object. Authorization is decided first, the body is then read under a size ceiling, and every rejection still produces an audit record.
health
async
¶
Report service liveness and which capabilities are available.
Source code in src/cryptography_manager/api/routes.py
cryptography
async
¶
Execute one cryptographic operation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request
|
Request
|
The incoming request, carrying application state. |
required |
authorization
|
str | None
|
Bearer token issued by the identity provider. |
Header(default=None)
|
Returns:
| Type | Description |
|---|---|
JSONResponse
|
The response envelope, with a status code reflecting the outcome. |
Source code in src/cryptography_manager/api/routes.py
Application entry point¶
main
¶
Service entry point.
Builds the FastAPI application and wires together the pieces a request needs: configuration, the manager that dispatches to backends, per-user budget accounting, audit logging and token verification. Everything is assembled once at startup and shared, because rebuilding adapters or re-reading budget state per request would be both slow and, in the budget's case, wrong.
create_app
¶
create_app(settings: Settings | None = None) -> FastAPI
Build the application.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
settings
|
Settings | None
|
Runtime settings; read from the environment when omitted. |
None
|
Returns:
| Type | Description |
|---|---|
FastAPI
|
The configured application. |
Source code in src/cryptography_manager/main.py
main
¶
Console script entry point: serve the API with uvicorn.