Secure (Compact JWS / JWE)
JSON APIs for payloads ≤ 5 MB**
1 · Scope
The Secure tag covers synchronous, in-memory cryptographic operations that travel as Base64-encoded JSON:
Function | RFC / Format | Notes |
---|---|---|
Sign / Verify | RFC 7515 – Compact JWS | Post-quantum (ML-DSA, Falcon) and classical (RSA-PSS, ECDSA). |
Encrypt / Decrypt | RFC 7516 – Compact JWE | Hybrid KEM+AEAD (ML-KEM-1024 + A256GCM, RSA-OAEP-256 + A256GCM, etc.). |
Re-sign / Re-encrypt | Seamless migration flows | Move payloads from classical → PQC keys with no plaintext exposure. |
Successful responses include a standard metadata envelope:
Field | Purpose |
---|---|
jwsToken / jweToken / decryptedData |
Output of the requested operation. |
keyRequested |
kid supplied by the caller. |
actualKeyUsed |
Effective kid after rotation / alias resolution. |
algorithmUsed |
Canonical algorithm (e.g. ML-KEM-768+A256GCM ). |
warnings[] |
Lifecycle hints (soft limits, nearing expiry, sunset dates). |
Conditional field –
migrationMode ← boolean
Included only by the /reencrypt and /resign endpoints (compact and streaming variants).
It istrue
when the server had to applysourceKidOverride
because the incoming JWE/JWS header had nokid
; it is absent otherwise.
All endpoints require a Bearer JWT (Authorization: Bearer <token>
).
Maximum decoded payload size is 5 MB — on overflow the API returns 413 Payload Too Large.
2 · Endpoints (tag Secure
)
Verb | Path | Summary | Request Schema | Success |
---|---|---|---|---|
POST | /api/crypto/encrypt |
Encrypt plaintext → Compact JWE | EncryptRequest |
200 OK |
POST | /api/crypto/decrypt |
Decrypt Compact JWE → plaintext | DecryptJweRequest |
200 OK |
POST | /api/crypto/sign |
Sign data → Compact JWS | SignRequest |
200 OK |
POST | /api/crypto/verify |
Verify Compact JWS | VerifyJwsRequest |
200 OK |
POST | /api/crypto/reencrypt |
Decrypt under oldKid & re-encrypt under newKid | ReencryptJweRequest |
200 OK |
POST | /api/crypto/resign |
Verify with oldKid & re-sign with newKid | ResignJwsRequest |
200 OK |
3 · Core Schemas
Schema | Direction | Used by |
---|---|---|
EncryptRequest / EncryptJweResponse | ⇅ | /encrypt |
DecryptJweRequest / DecryptResponse | ⇅ | /decrypt |
SignRequest / SignJwsResponse | ⇅ | /sign |
VerifyJwsRequest / VerifySignatureResponse | ⇅ | /verify |
ReencryptJweRequest / ReencryptJweResponse | ⇅ | /reencrypt |
ResignJwsRequest / ResignJwsResponse | ⇅ | /resign |
See the OpenAPI spec (#/components/schemas/*
) for full field lists.
4 · Encrypt – Quick Start
200 OK{
"jweToken" : "eyJraWQiOiJteVB1YmxpY0tpZCIsImFsZyI6Ik1MLUtFTS0xMDI0K0EyNTZHQ00ifQ..iv.ciphertext.tag",
"keyRequested" : "myPublicKid",
"actualKeyUsed" : "myPublicKid_v2",
"algorithmUsed" : "ML-KEM-1024+A256GCM",
"warnings" : []
}
5 - Decrypt -- Quick Start
200 OK
{
"decryptedData" : "SGVsbG8gQW5rYQ==",
"keyRequested" : "myPrivateKid",
"actualKeyUsed" : "myPrivateKid",
"algorithmUsed" : "ML-KEM-768",
"warnings" : []
}
6 - Sign -- Quick Start
200 OK{
"jwsToken" : "eyJraWQiOiJteVNpZ25pbmdLaWQiLCJhbGciOiJGQUxDT04tNTEyIn0.SGVsbG8gQW5rYQ.<sig>",
"keyRequested" : "mySigningKid",
"actualKeyUsed" : "mySigningKid",
"algorithmUsed" : "Falcon-512",
"warnings" : []
}
7 - Verify -- Quick Start
200 OK{
"valid" : true,
"keyRequested" : "myVerifyKid",
"actualKeyUsed" : "myVerifyKid",
"algorithmUsed" : "Falcon-512",
"warnings" : []
}
8 - Re-encrypt -- Quick Start
{
"jweToken" : "<legacy-rsa-jwe>",
"newKid" : "pqk-mlkem-768",
"sourceKidOverride": "oldRsaKid" // OPTIONAL – use only when the JWE header has no kid
}
Two possible 200 OK
response
- Standard response (header already contained a kid)
- Response when sourceKidOverride
was applied
{
"jweToken" : "<new-pq-jwe>",
"oldKeyRequested" : "oldRsaKid", // came from sourceKidOverride
"oldKeyUsed" : "oldRsaKid_v2",
"oldKeyAlgorithmUsed" : "RSA-2048",
"newKeyRequested" : "pqk-mlkem-768",
"newKeyUsed" : "pqk-mlkem-768",
"newKeyAlgorithmUsed" : "ML-KEM-768",
"migrationMode" : true, // indicates override
"warnings" : ["Old key sunset in 30 days"]
}
9 - Re-sign -- Quick Start
{
"jwsToken" : "<rsa-ps256-token>",
"newKid" : "pqk-falcon-512",
"sourceKidOverride": "oldRsaKid" // OPTIONAL – only if Compact JWS header has no kid
}
Two possible 200 OK
responses
- Standard response (header contained kid)
- Response when sourceKidOverride
was applied
{
"jwsToken" : "<new-falcon-token>",
"oldKeyRequested" : "oldRsaKid", // came from sourceKidOverride
"oldKeyUsed" : "oldRsaKid_v2",
"oldKeyAlgorithmUsed" : "PS256",
"newKeyRequested" : "pqk-falcon-512",
"newKeyUsed" : "pqk-falcon-512",
"newKeyAlgorithmUsed" : "Falcon-512",
"migrationMode" : true, // indicates override
"warnings" : []
}
10 - Compact JWE / JWS Anatomy
10.1 Compact JWE (5 parts)
- header -- JSON withalg
, enc
, kid
, ...
-
encryptedKey -- CEK wrapped by the recipient's public key (absent when
alg=dir
). -
iv -- IV of the AEAD cipher.
-
ciphertext -- Encrypted payload.
-
tag -- Authentication tag.
10.2 Compact JWS (3 parts)
- header -- JSON withalg
, kid
, ...
-
payload -- Data (Base64URL).
-
signature -- Digital signature over header.payload.
Tip -- Clients can decode the first segment (
header
) locally to inspectkid
andalg
before calling the API.
11 - Error Handling (RFC 7807)
Code | type URI |
Trigger |
---|---|---|
400 | /errors/invalid-input |
Malformed JSON/Base64, missing field, incompatible algorithm. |
401 | /errors/unauthorized |
Missing or invalid credentials. |
404 | /errors/not-found |
kid unsuitable or absent. |
409 | /errors/conflict |
Key revoked, suspended, or lifecycle mismatch. |
413 | /errors/payload-too-large |
Payload > 5 MB (decoded). |
422 | /errors/unprocessable-entity |
Malformed Compact JWE/JWS. |
500 | /errors/internal |
Unexpected crypto-engine failure. |
Problem documents include timestamp
, detail
, and instance
, and honour Accept-Language: en | es
.
12 - Best Practices
-
Monitor
warnings[]
--- rotate keys before hard limits hit. -
Cache
algorithmUsed
to avoid extra discovery calls. -
Prefer ML-KEM-1024 for archival data ≥ 30 years.
-
Switch to streaming endpoints for files approaching 5 MB.
-
Schedule periodic re-encrypt/re-sign to maintain forward secrecy.
13 - Security
All Secure endpoints use the bearerAuth
scheme defined in the OpenAPI:
Authorization: Bearer <JWT>
--- obtain the token from your OIDC IdP.
Document version 2.1 -- generated from OpenAPI build 2025-05-31.\ © 2025 AnkaTech Co. All rights reserved.