{
	"info": {
		"name": "ANKASecure API – Enterprise Post-Quantum Cryptography",
		"description": {
		    "content": "Enterprise-grade quantum-resistant cryptography API with hybrid classical+PQC encryption, zero-copy streaming for large files, and NIST-standardized algorithms.\n\n✓ Hybrid cryptography (X25519+ML-KEM) for crypto-agility\n✓ Streaming operations for multi-GB files without buffering\n✓ Implements ML-KEM (FIPS 203) and ML-DSA (FIPS 204)\n✓ Multi-tenant key isolation with complete lifecycle management\n✓ Interoperability with external PKI systems\n\nAlgorithms: AES · RSA · ECC · ML-KEM · ML-DSA · Falcon · SLH-DSA\n",
		    "type": "text/markdown"
		},
		"version": "3.2.0",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
	        {
	            "name": " Algorithm Catalog",
	            "description": "Catalog of supported cryptographic algorithms for crypto-agility decisions.",
	            "item": [
	                        {
    "name": "/api/v3/key-management/supported-algorithms",
                "description": "Returns the algorithm catalogue with full metadata for crypto-agility decisions. Supports optional server-side filtering via query parameters.  ## Query Parameters (all optional)  | Parameter | Type | Logic | Description | |-----------|------|-------|-------------| | `category` | string | = | CLASSICAL, POST_QUANTUM, or HYBRID | | `status` | string | = | RECOMMENDED, EXPERIMENTAL, or LEGACY | | `minSecurityLevel` | int | >= | Minimum NIST level (1, 3, 5) | | `maxSecurityLevel` | int | <= | Maximum NIST level (1, 3, 5) | | `keyOps` | array | AND | Required operations (must support ALL) | | `standards` | array | AND | Required standards (must have ALL) | | `kty` | array | OR | Published key types (matches ANY, including COMPOSITE). An unpublished token is refused with 400 | | `alg` | array | OR | Algorithms (matches ANY) |  ## Response fields  | Field | Type | Description | |-------|------|-------------| | `kty` | string | Key type, one of the published tokens: ML-KEM, HQC, FRODO, CMCE, BIKE, SABER, NTRU, NTRUPRIME, SMAUG-T, ML-DSA, SLH-DSA, FALCON, XMSS, LMS, EC, RSA, oct, OKP, SM2, GOST-EC (simple), or COMPOSITE (every hybrid pairing) | | `compositeMode` | string | How a hybrid entry's components are combined. Present only on composite entries | | `alg` | string | Algorithm identifier: ML-KEM-768, RSA-4096 (simple) or X25519+ML-KEM-768 (composite) | | `keyOps` | array | Permitted operations (sign, verify, encrypt, decrypt), in RFC 7517 §4.3 order | | `status` | string | RECOMMENDED, EXPERIMENTAL, or LEGACY | | `sunsetDate` | date | Planned deprecation date (ISO 8601, optional) | | `advisory` | string | Migration or security guidance (optional) | | `securityLevel` | integer | NIST security level (1-5) | | `standards` | array | Endorsing bodies, in the order of the single platform vocabulary: NIST, ETSI, NSA, ISO, BSI, ANSSI, ENISA, IETF, KISA, CRYPTREC, GMT, MYSEAL, NCA_NCS, GOST | | `category` | string | CLASSICAL, POST_QUANTUM, or HYBRID |  ## Composite algorithm entries  Composite algorithms appear as first-class entries with: - `category: \"HYBRID\"` - `kty`: the single coarse token `COMPOSITE`, for every hybrid pairing - `compositeMode`: how the components are combined — the construction, on its own axis - `alg`: Combined identifier (e.g., \"X25519+ML-KEM-768\", \"Ed25519+ML-DSA-65\")  Use `category=HYBRID` to filter composite entries only.  ## Example queries  ``` # Post-quantum algorithms only GET /api/v3/key-management/supported-algorithms?category=POST_QUANTUM  # Hybrid/composite algorithms only GET /api/v3/key-management/supported-algorithms?category=HYBRID  # High security, recommended algorithms GET /api/v3/key-management/supported-algorithms?minSecurityLevel=3&status=RECOMMENDED  # Signature algorithms attributed to NIST GET /api/v3/key-management/supported-algorithms?keyOps=sign,verify&standards=NIST  # Find specific composite algorithm GET /api/v3/key-management/supported-algorithms?alg=X25519+ML-KEM-768 ``` ",
                 "item": [
                            {
                                "name": "Get supported algorithms (crypto-agility)",
                                "request": {
    "method": "GET",
    "header": [
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/key-management/supported-algorithms",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "key-management",
        "supported-algorithms"
    ],
    "variable": [
    ],
    "query": [
        {
        "key": "category",
        "value": "category_example",
        "description": "Filter by category: CLASSICAL, POST_QUANTUM, or HYBRID",
        "disabled": true
        },
        {
        "key": "status",
        "value": "status_example",
        "description": "Filter by status: RECOMMENDED, EXPERIMENTAL, or LEGACY",
        "disabled": true
        },
        {
        "key": "minSecurityLevel",
        "value": "56",
        "description": "Minimum NIST security level (1, 3, or 5)",
        "disabled": true
        },
        {
        "key": "maxSecurityLevel",
        "value": "56",
        "description": "Maximum NIST security level (1, 3, or 5)",
        "disabled": true
        },
        {
        "key": "keyOps",
        "value": "",
        "description": "Required operations (comma-separated). Must support ALL specified.",
        "disabled": true
        },
        {
        "key": "standards",
        "value": "",
        "description": "Required standards (comma-separated). Must have ALL specified.",
        "disabled": true
        },
        {
        "key": "kty",
        "value": "",
        "description": "Key types (comma-separated, OR logic). Matches ANY specified. Use COMPOSITE for hybrid algorithms — a composite entry's construction is selected with compositeMode, not here. An unpublished token is a 400 that names the accepted set, never a silently empty page.",
        "disabled": true
        },
        {
        "key": "alg",
        "value": "",
        "description": "Algorithms (comma-separated, OR logic). Matches ANY specified.",
        "disabled": true
        },
        {
        "key": "compositeMode",
        "value": "",
        "description": "Composite construction modes (comma-separated, OR logic): COMPOSITE_KEM_COMBINE or COMPOSITE_SIGNATURE. Selects among hybrid algorithms, which all publish kty=COMPOSITE. Simple algorithms never match. An unpublished construction is a 400 that names the accepted set, never a silently empty page.",
        "disabled": true
        }
    ]
    },
    "description": "Returns the algorithm catalogue with full metadata for crypto-agility decisions. Supports optional server-side filtering via query parameters.  ## Query Parameters (all optional)  | Parameter | Type | Logic | Description | |-----------|------|-------|-------------| | `category` | string | = | CLASSICAL, POST_QUANTUM, or HYBRID | | `status` | string | = | RECOMMENDED, EXPERIMENTAL, or LEGACY | | `minSecurityLevel` | int | >= | Minimum NIST level (1, 3, 5) | | `maxSecurityLevel` | int | <= | Maximum NIST level (1, 3, 5) | | `keyOps` | array | AND | Required operations (must support ALL) | | `standards` | array | AND | Required standards (must have ALL) | | `kty` | array | OR | Published key types (matches ANY, including COMPOSITE). An unpublished token is refused with 400 | | `alg` | array | OR | Algorithms (matches ANY) |  ## Response fields  | Field | Type | Description | |-------|------|-------------| | `kty` | string | Key type, one of the published tokens: ML-KEM, HQC, FRODO, CMCE, BIKE, SABER, NTRU, NTRUPRIME, SMAUG-T, ML-DSA, SLH-DSA, FALCON, XMSS, LMS, EC, RSA, oct, OKP, SM2, GOST-EC (simple), or COMPOSITE (every hybrid pairing) | | `compositeMode` | string | How a hybrid entry's components are combined. Present only on composite entries | | `alg` | string | Algorithm identifier: ML-KEM-768, RSA-4096 (simple) or X25519+ML-KEM-768 (composite) | | `keyOps` | array | Permitted operations (sign, verify, encrypt, decrypt), in RFC 7517 §4.3 order | | `status` | string | RECOMMENDED, EXPERIMENTAL, or LEGACY | | `sunsetDate` | date | Planned deprecation date (ISO 8601, optional) | | `advisory` | string | Migration or security guidance (optional) | | `securityLevel` | integer | NIST security level (1-5) | | `standards` | array | Endorsing bodies, in the order of the single platform vocabulary: NIST, ETSI, NSA, ISO, BSI, ANSSI, ENISA, IETF, KISA, CRYPTREC, GMT, MYSEAL, NCA_NCS, GOST | | `category` | string | CLASSICAL, POST_QUANTUM, or HYBRID |  ## Composite algorithm entries  Composite algorithms appear as first-class entries with: - `category: \"HYBRID\"` - `kty`: the single coarse token `COMPOSITE`, for every hybrid pairing - `compositeMode`: how the components are combined — the construction, on its own axis - `alg`: Combined identifier (e.g., \"X25519+ML-KEM-768\", \"Ed25519+ML-DSA-65\")  Use `category=HYBRID` to filter composite entries only.  ## Example queries  ``` # Post-quantum algorithms only GET /api/v3/key-management/supported-algorithms?category=POST_QUANTUM  # Hybrid/composite algorithms only GET /api/v3/key-management/supported-algorithms?category=HYBRID  # High security, recommended algorithms GET /api/v3/key-management/supported-algorithms?minSecurityLevel=3&status=RECOMMENDED  # Signature algorithms attributed to NIST GET /api/v3/key-management/supported-algorithms?keyOps=sign,verify&standards=NIST  # Find specific composite algorithm GET /api/v3/key-management/supported-algorithms?alg=X25519+ML-KEM-768 ``` "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": " Secure Streaming",
	            "description": "Endpoints to manage fully streaming-based cryptographic operations\nwith symmetric and post-quantum/classical asymmetric keys (AES, RSA, ECC, ML-1024,\nML-DSA, Falcon, etc.).\n",
	            "item": [
	                        {
    "name": "/api/v3/crypto/stream/decrypt",
                "description": "The request is <strong>multipart/mixed</strong> with two parts: <ol>   <li><code>application/jose+json</code> — JWE General-JSON header       (detached ciphertext).</li>   <li><code>application/octet-stream</code> — proprietary binary       envelope followed by the ciphertext and GCM tag.</li> </ol> The response is <strong>multipart/mixed</strong>: PART&nbsp;1 (<code>application/octet-stream</code>) is the decrypted plaintext and the trailing PART&nbsp;2 (<code>application/json</code>) is a <code>StreamVerdict</code> emitted AFTER the end-of-stream AES-GCM tag is verified (<code>{verdict,operation,reason,correlationId,timestamp}</code>). Because the GCM tag is only known at end-of-stream, a tamper is reported through an <code>INVALID</code> verdict in PART&nbsp;2 — never a silently truncated success.<br><br> <strong>Supports SIMPLE keys</strong> (single recipient), <strong>COMPOSITE keys</strong> (one recipient per component, the key named by the <code>kid</code> in <code>protected</code>; decryption uses all of them to derive the content encryption key) <strong>and JWEs addressed to several keys</strong> (one recipient per key, each naming its key in its own header, no <code>kid</code> in <code>protected</code> - the General JSON JWE of RFC 7516 section 7.2.1 the PKCS#7 conversion emits for several recipients).<br><br> <strong>A JWE addressed to several keys is read with the ONE recipient the caller names</strong> in the <code>recipientKid</code> query parameter (RFC 7516 section 5.2 leaves the choice to the application). Everything below happens on the request, before any payload byte is read or written, in this order: the header is classified from its public members alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the parameter and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) - a refusal is the generic 403, which names no key; a composite key as the named recipient is refused with 422; and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. For a single-recipient or composite JWE <code>recipientKid</code> is optional and, when present, must name the one key the JWE names. ",
                 "item": [
                            {
                                "name": "Decrypt data (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/decrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "decrypt"
    ],
    "variable": [
    ],
    "query": [
        {
        "key": "recipientKid",
        "value": "acme-archive-r2",
        "description": "The recipient of the JWE this decryption reads, named by its key identifier. Required when the JWE is addressed to several keys (no `kid` in `protected`, a `kid` in every recipient header): exactly one grant and one lifecycle decision are taken, on this key only, and only its `encrypted_key` is unwrapped. Optional for a single-recipient or composite JWE; when present it must name the one key the JWE names. Given at most once.",
        "disabled": true
        }
    ]
    },
    "description": "The request is <strong>multipart/mixed</strong> with two parts: <ol>   <li><code>application/jose+json</code> — JWE General-JSON header       (detached ciphertext).</li>   <li><code>application/octet-stream</code> — proprietary binary       envelope followed by the ciphertext and GCM tag.</li> </ol> The response is <strong>multipart/mixed</strong>: PART&nbsp;1 (<code>application/octet-stream</code>) is the decrypted plaintext and the trailing PART&nbsp;2 (<code>application/json</code>) is a <code>StreamVerdict</code> emitted AFTER the end-of-stream AES-GCM tag is verified (<code>{verdict,operation,reason,correlationId,timestamp}</code>). Because the GCM tag is only known at end-of-stream, a tamper is reported through an <code>INVALID</code> verdict in PART&nbsp;2 — never a silently truncated success.<br><br> <strong>Supports SIMPLE keys</strong> (single recipient), <strong>COMPOSITE keys</strong> (one recipient per component, the key named by the <code>kid</code> in <code>protected</code>; decryption uses all of them to derive the content encryption key) <strong>and JWEs addressed to several keys</strong> (one recipient per key, each naming its key in its own header, no <code>kid</code> in <code>protected</code> - the General JSON JWE of RFC 7516 section 7.2.1 the PKCS#7 conversion emits for several recipients).<br><br> <strong>A JWE addressed to several keys is read with the ONE recipient the caller names</strong> in the <code>recipientKid</code> query parameter (RFC 7516 section 5.2 leaves the choice to the application). Everything below happens on the request, before any payload byte is read or written, in this order: the header is classified from its public members alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the parameter and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) - a refusal is the generic 403, which names no key; a composite key as the named recipient is refused with 422; and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. For a single-recipient or composite JWE <code>recipientKid</code> is optional and, when present, must name the one key the JWE names. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/decrypt-verify",
                "description": "Consumes the nested ciphertext as <code>multipart/mixed</code> (outer JWE header + ciphertext), decrypts it and verifies the recovered inner JWS. The response is <code>multipart/mixed</code>: PART&nbsp;1 is the decrypted plaintext, PART&nbsp;2 a JSON verdict carrying <code>gcmTagVerdict</code>, <code>signatureVerdict</code> and <code>signatureResults</code> (one entry per inner signature: its <code>kid</code>, <code>algorithm</code>, <code>materialVersion</code> and <code>verified</code>) — both verdicts MUST be VALID for the overall <code>verdict</code> to be VALID.<br><br> <b>Several keys.</b> An outer JWE addressed to several keys is decrypted with the ONE recipient the <code>recipientKid</code> query parameter names: its DECRYPT grant and lifecycle are decided before the body starts, and a refusal there is a problem answered with no body byte. The inner JWS may carry one signature (Compact) or several (the General JSON JWS a PKCS#7 conversion writes, <code>payload</code> first): every signer passes its VERIFY grant and lifecycle, for the caller of this request, before its signature is checked, and the <code>signatureVerdict</code> is VALID only when every signature verifies. Because the inner signers are readable only after the 200 is committed, three refusals are reported as <code>signatureVerdict</code> INVALID rather than as a status: a signer the caller may not verify with (403 on <code>/decrypt-verify</code>), a signature that does not verify (422 there), and a decrypting recipient that is also an inner signer (400 there). While the signatures of a General inner JWS are unread its payload segment is held in a bounded temporary file, encrypted under a key of its own and deleted when the verdict is known.<br><br> The inner JWS may be signed by any signing key this platform issues - symmetric, asymmetric or composite - and the outer JWE addressed to any encryption key, so every output of <code>/stream/sign-encrypt</code> is accepted here. A composite inner signature is verified as one value (both components must verify) and its protected <code>iat</code>/<code>exp</code> are enforced as for a SIMPLE key; its outcome is the <code>signatureVerdict</code>, VALID or INVALID. As for every inner key, the plaintext of PART&nbsp;1 may be streamed before the verdict is known: a caller MUST NOT use it unless the overall <code>verdict</code> is VALID. ",
                 "item": [
                            {
                                "name": "Decrypt-then-verify data (streaming, two verdicts).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/decrypt-verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "decrypt-verify"
    ],
    "variable": [
    ],
    "query": [
        {
        "key": "recipientKid",
        "value": "acme-legal-rsa",
        "description": "The recipient of the outer JWE this operation decrypts with, named by its key identifier. Required when the JWE is addressed to several keys (no `kid` in `protected`, a `kid` in every recipient header): exactly one grant and one lifecycle decision are taken on it, and only its `encrypted_key` is unwrapped. Optional for a single-recipient or composite JWE; when present it must name the one key the JWE names. It must be none of the inner JWS's signers. Given at most once; absent where required, or naming no recipient, the request is refused with 400 naming it.",
        "disabled": true
        }
    ]
    },
    "description": "Consumes the nested ciphertext as <code>multipart/mixed</code> (outer JWE header + ciphertext), decrypts it and verifies the recovered inner JWS. The response is <code>multipart/mixed</code>: PART&nbsp;1 is the decrypted plaintext, PART&nbsp;2 a JSON verdict carrying <code>gcmTagVerdict</code>, <code>signatureVerdict</code> and <code>signatureResults</code> (one entry per inner signature: its <code>kid</code>, <code>algorithm</code>, <code>materialVersion</code> and <code>verified</code>) — both verdicts MUST be VALID for the overall <code>verdict</code> to be VALID.<br><br> <b>Several keys.</b> An outer JWE addressed to several keys is decrypted with the ONE recipient the <code>recipientKid</code> query parameter names: its DECRYPT grant and lifecycle are decided before the body starts, and a refusal there is a problem answered with no body byte. The inner JWS may carry one signature (Compact) or several (the General JSON JWS a PKCS#7 conversion writes, <code>payload</code> first): every signer passes its VERIFY grant and lifecycle, for the caller of this request, before its signature is checked, and the <code>signatureVerdict</code> is VALID only when every signature verifies. Because the inner signers are readable only after the 200 is committed, three refusals are reported as <code>signatureVerdict</code> INVALID rather than as a status: a signer the caller may not verify with (403 on <code>/decrypt-verify</code>), a signature that does not verify (422 there), and a decrypting recipient that is also an inner signer (400 there). While the signatures of a General inner JWS are unread its payload segment is held in a bounded temporary file, encrypted under a key of its own and deleted when the verdict is known.<br><br> The inner JWS may be signed by any signing key this platform issues - symmetric, asymmetric or composite - and the outer JWE addressed to any encryption key, so every output of <code>/stream/sign-encrypt</code> is accepted here. A composite inner signature is verified as one value (both components must verify) and its protected <code>iat</code>/<code>exp</code> are enforced as for a SIMPLE key; its outcome is the <code>signatureVerdict</code>, VALID or INVALID. As for every inner key, the plaintext of PART&nbsp;1 may be streamed before the verdict is known: a caller MUST NOT use it unless the overall <code>verdict</code> is VALID. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/encrypt",
                "description": "Consumes two <code>multipart/form-data</code> fields:<br> 1. <code>metadata</code> – JSON body <em>EncryptStreamRequest</em><br> 2. <code>file</code> – binary plaintext<br><br> Produces a <strong>multipart/mixed</strong> response where:<br> • Part 1 (<code>application/jose+json</code>) is a JWE General-JSON header with   detached ciphertext.<br> • Part 2 (<code>application/octet-stream</code>) is the proprietary envelope   <code>[wkLen]‖wrappedKey‖[ivLen]‖iv‖ciphertext‖tag</code> streamed on-the-fly.<br><br> Output format depends on key type:<br> • SIMPLE keys: JWE General JSON with single recipient<br> • COMPOSITE keys: JWE General JSON with multiple recipients (one per component) ",
                 "item": [
                            {
                                "name": "Encrypt data (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Consumes two <code>multipart/form-data</code> fields:<br> 1. <code>metadata</code> – JSON body <em>EncryptStreamRequest</em><br> 2. <code>file</code> – binary plaintext<br><br> Produces a <strong>multipart/mixed</strong> response where:<br> • Part 1 (<code>application/jose+json</code>) is a JWE General-JSON header with   detached ciphertext.<br> • Part 2 (<code>application/octet-stream</code>) is the proprietary envelope   <code>[wkLen]‖wrappedKey‖[ivLen]‖iv‖ciphertext‖tag</code> streamed on-the-fly.<br><br> Output format depends on key type:<br> • SIMPLE keys: JWE General JSON with single recipient<br> • COMPOSITE keys: JWE General JSON with multiple recipients (one per component) "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/reencrypt",
                "description": "Decrypts the incoming ciphertext using <code>oldKid</code> (from the JWE header) and re-encrypts it on the fly with <code>newKid</code> (provided via query parameter). Returns a <strong>multipart/mixed</strong> response: the new JWE header part, the re-encrypted ciphertext part, and a trailing <code>application/json</code> <code>StreamVerdict</code> part emitted AFTER the source AES-GCM tag is verified at end-of-stream (an <code>INVALID</code> verdict signals a tampered source; no committed ciphertext is promotable). All key-selection metadata is returned in the single `Crypto-Policy-Info` response header.<br><br> The two keys must be of one class: both symmetric, or both asymmetric (a composite key is asymmetric). A pair whose classes differ is refused with 400 <code>key-operation-incompatible</code> after the grant, lifecycle and capability checks and before any body byte is read; the source key's class is the one of the material its <code>ank_kv</code> pins. Over a pair of one class:<br> • SIMPLE → SIMPLE (single recipient → single recipient)<br> • SIMPLE → COMPOSITE (single recipient → multiple recipients; the SIMPLE source is asymmetric)<br> • COMPOSITE → COMPOSITE (multiple recipients → multiple recipients)<br> • COMPOSITE → SIMPLE (multiple recipients → single recipient; the SIMPLE target is asymmetric)<br> Every pair is accepted on this route exactly as on the buffered <code>/reencrypt</code>.<br><br> <strong>A JWE addressed to several keys</strong> (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>): the <code>sourceKid</code> query parameter names the ONE recipient replaced, whose <code>encrypted_key</code> alone is unwrapped; the new header keeps every other recipient in its position with <code>newKid</code> at the replaced one, under a FRESH content-encryption key (the replaced key cannot read the output), each kept recipient re-wrapped at the PRIMARY its write gate judged, as the new <code>ank_kvs</code> records. The caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> and to every kept recipient, and no <code>DECRYPT</code> grant; every grant, then every key-lifecycle decision (replaced key on DECRYPT, <code>newKid</code> on REENCRYPT, kept recipients on ENCRYPT), is decided before any body byte. A recipient entry outside the protected set is refused (<code>JWE_RECIPIENT_SET_UNPROTECTED</code>), and a source whose tag fails at end-of-stream leaves the output without its tag and the verdict <code>INVALID</code>. The recipient set is authenticated by that same source tag, and on this route the tag is verified only at the end of the stream: the re-wrapped keys and the re-encrypted content are streamed before it is. What bounds who can receive the content before a tag failure is therefore the caller's <code>REENCRYPT</code> grant from the replaced key to every kept recipient, decided before any body byte, not the tag. ",
                 "item": [
                            {
                                "name": "Re-encrypt data (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/reencrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "reencrypt"
    ],
    "variable": [
    ],
    "query": [
        {
        "key": "newKid",
        "value": "acme-archive-r4",
        "description": "KID of the key the payload is re-encrypted TO. For a JWE addressed to several keys it takes the position of the replaced recipient, and must not be one of the recipients the operation keeps (400 naming `newKid`). Given at most once.",
        "disabled": false
        },
        {
        "key": "sourceKid",
        "value": "acme-archive-r2",
        "description": "The recipient this re-encryption replaces, named by its key identifier. Required when the JWE is addressed to several keys (no `kid` in `protected`, a `kid` in every recipient header): it must name exactly one recipient, whose `encrypted_key` alone is unwrapped. When the header names one key it is optional and, present, must equal it; when the header names none it is required and names the key the payload is decrypted FROM. Otherwise 400 naming this parameter and no key. Given at most once.",
        "disabled": true
        }
    ]
    },
    "description": "Decrypts the incoming ciphertext using <code>oldKid</code> (from the JWE header) and re-encrypts it on the fly with <code>newKid</code> (provided via query parameter). Returns a <strong>multipart/mixed</strong> response: the new JWE header part, the re-encrypted ciphertext part, and a trailing <code>application/json</code> <code>StreamVerdict</code> part emitted AFTER the source AES-GCM tag is verified at end-of-stream (an <code>INVALID</code> verdict signals a tampered source; no committed ciphertext is promotable). All key-selection metadata is returned in the single `Crypto-Policy-Info` response header.<br><br> The two keys must be of one class: both symmetric, or both asymmetric (a composite key is asymmetric). A pair whose classes differ is refused with 400 <code>key-operation-incompatible</code> after the grant, lifecycle and capability checks and before any body byte is read; the source key's class is the one of the material its <code>ank_kv</code> pins. Over a pair of one class:<br> • SIMPLE → SIMPLE (single recipient → single recipient)<br> • SIMPLE → COMPOSITE (single recipient → multiple recipients; the SIMPLE source is asymmetric)<br> • COMPOSITE → COMPOSITE (multiple recipients → multiple recipients)<br> • COMPOSITE → SIMPLE (multiple recipients → single recipient; the SIMPLE target is asymmetric)<br> Every pair is accepted on this route exactly as on the buffered <code>/reencrypt</code>.<br><br> <strong>A JWE addressed to several keys</strong> (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>): the <code>sourceKid</code> query parameter names the ONE recipient replaced, whose <code>encrypted_key</code> alone is unwrapped; the new header keeps every other recipient in its position with <code>newKid</code> at the replaced one, under a FRESH content-encryption key (the replaced key cannot read the output), each kept recipient re-wrapped at the PRIMARY its write gate judged, as the new <code>ank_kvs</code> records. The caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> and to every kept recipient, and no <code>DECRYPT</code> grant; every grant, then every key-lifecycle decision (replaced key on DECRYPT, <code>newKid</code> on REENCRYPT, kept recipients on ENCRYPT), is decided before any body byte. A recipient entry outside the protected set is refused (<code>JWE_RECIPIENT_SET_UNPROTECTED</code>), and a source whose tag fails at end-of-stream leaves the output without its tag and the verdict <code>INVALID</code>. The recipient set is authenticated by that same source tag, and on this route the tag is verified only at the end of the stream: the re-wrapped keys and the re-encrypted content are streamed before it is. What bounds who can receive the content before a tag failure is therefore the caller's <code>REENCRYPT</code> grant from the replaced key to every kept recipient, decided before any body byte, not the tag. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/resign",
                "description": "Verifies a detached-JWS (<code>oldJws</code>) under <code>oldKid</code>— the header's <code>kid</code>, which <code>sourceKid</code> may name and must then equal, or the key <code>sourceKid</code> names when the header lacks one—and immediately signs the same payload with <code>newKid</code>, in one read of the payload. The response is <strong>multipart/mixed</strong>: PART&nbsp;1 (<code>application/octet-stream</code>) is the new detached-JWS JSON and the trailing PART&nbsp;2 (<code>application/json</code>) is the <code>VALID</code> <code>StreamVerdict</code>. Nothing is written until the source verified and the new signature exists: a source signature that does not verify is 400 <code>invalid-input</code> with no body part, the status of every re-sign on every key flavour and both planes.<br><br> <strong>A detached JWS signed by several keys</strong> (the General body, one signature per key): <code>sourceKid</code> is REQUIRED and names the ONE signer replaced, and <code>newKid</code> must be none of the kept signers (400 naming the member, before any key is gated). The caller holds <code>RESIGN</code> on <code>sourceKid</code> → <code>newKid</code> and <code>VERIFY</code> on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected <code>ank_kv</code> and <code>newKid</code> on the RESIGN row, all before any payload byte is read. The payload is then read ONCE into every signature and the new one together; the new signature is completed only when EVERY signature verified. PART&nbsp;1 is the General detached JWS with the new signature, under a protected header built fresh for <code>newKid</code>, at the replaced position and every other signature (<code>protected</code>, <code>header</code>, <code>signature</code>) as received. A member given twice in <code>metadata</code> is 400 naming it. When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its <code>sigTst</code> in its own entry's <code>header</code>, as a single-key re-sign carries it; every other signature keeps its <code>header</code>, and so its own timestamp, unchanged.<br><br> The replaced signature's key and its replacement must be of one class: both symmetric, or both asymmetric (a composite key is asymmetric). A pair whose classes differ is refused with 400 <code>key-operation-incompatible</code> after the grant, lifecycle and capability checks and before any payload byte is read; a JWS signed by several keys admits no symmetric signer at all (422 <code>JOSE_SYMMETRIC_ACTOR</code>). Over a pair of one class:<br> • SIMPLE → SIMPLE<br> • SIMPLE → COMPOSITE<br> • COMPOSITE → COMPOSITE<br> • COMPOSITE → SIMPLE<br> Every key signs with one signature (a composite key's is one composite value), so a source signed by one key carries one signature and its result one, and a source signed by several keys carries one signature per key and so does its result. A composite source is named by its protected header, so <code>sourceKid</code> may not supply a composite key for a signature whose header names none. ",
                 "item": [
                            {
                                "name": "Re-sign data (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/resign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "resign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies a detached-JWS (<code>oldJws</code>) under <code>oldKid</code>— the header's <code>kid</code>, which <code>sourceKid</code> may name and must then equal, or the key <code>sourceKid</code> names when the header lacks one—and immediately signs the same payload with <code>newKid</code>, in one read of the payload. The response is <strong>multipart/mixed</strong>: PART&nbsp;1 (<code>application/octet-stream</code>) is the new detached-JWS JSON and the trailing PART&nbsp;2 (<code>application/json</code>) is the <code>VALID</code> <code>StreamVerdict</code>. Nothing is written until the source verified and the new signature exists: a source signature that does not verify is 400 <code>invalid-input</code> with no body part, the status of every re-sign on every key flavour and both planes.<br><br> <strong>A detached JWS signed by several keys</strong> (the General body, one signature per key): <code>sourceKid</code> is REQUIRED and names the ONE signer replaced, and <code>newKid</code> must be none of the kept signers (400 naming the member, before any key is gated). The caller holds <code>RESIGN</code> on <code>sourceKid</code> → <code>newKid</code> and <code>VERIFY</code> on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected <code>ank_kv</code> and <code>newKid</code> on the RESIGN row, all before any payload byte is read. The payload is then read ONCE into every signature and the new one together; the new signature is completed only when EVERY signature verified. PART&nbsp;1 is the General detached JWS with the new signature, under a protected header built fresh for <code>newKid</code>, at the replaced position and every other signature (<code>protected</code>, <code>header</code>, <code>signature</code>) as received. A member given twice in <code>metadata</code> is 400 naming it. When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its <code>sigTst</code> in its own entry's <code>header</code>, as a single-key re-sign carries it; every other signature keeps its <code>header</code>, and so its own timestamp, unchanged.<br><br> The replaced signature's key and its replacement must be of one class: both symmetric, or both asymmetric (a composite key is asymmetric). A pair whose classes differ is refused with 400 <code>key-operation-incompatible</code> after the grant, lifecycle and capability checks and before any payload byte is read; a JWS signed by several keys admits no symmetric signer at all (422 <code>JOSE_SYMMETRIC_ACTOR</code>). Over a pair of one class:<br> • SIMPLE → SIMPLE<br> • SIMPLE → COMPOSITE<br> • COMPOSITE → COMPOSITE<br> • COMPOSITE → SIMPLE<br> Every key signs with one signature (a composite key's is one composite value), so a source signed by one key carries one signature and its result one, and a source signed by several keys carries one signature per key and so does its result. A composite source is named by its protected header, so <code>sourceKid</code> may not supply a composite key for a signature whose header names none. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/sign",
                "description": "Consumes two <code>multipart/form-data</code> fields:<br> 1. <code>metadata</code> — JSON body <em>SignStreamRequest</em><br> 2. <code>file</code> — binary data to sign<br><br> Produces a detached-JWS in JSON format streamed as <code>application/octet-stream</code>. Every key type writes the same flattened <code>{protected, signature}</code> document (RFC 7797, <code>\"b64\":false</code>, <code>\"crit\":[\"b64\"]</code>); only the header differs:<br> • SIMPLE keys: one signature, named by <code>kid</code> and <code>alg</code><br> • COMPOSITE keys: one composite signature (the ML-DSA and classical component signatures   in one value) over the RFC 7797 unencoded payload, under the protected header   <code>{alg, b64, crit, kid, ank_kv, iat}</code>: the composite <code>alg</code>, the   RFC 7797 members, <code>kid</code>, <code>ank_kv</code>, and <code>iat</code> whenever   this deployment's JWS local clock issues it. This operation takes no   <code>validityDays</code>, so the header carries no <code>exp</code>. ",
                 "item": [
                            {
                                "name": "Sign data (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/sign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "sign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Consumes two <code>multipart/form-data</code> fields:<br> 1. <code>metadata</code> — JSON body <em>SignStreamRequest</em><br> 2. <code>file</code> — binary data to sign<br><br> Produces a detached-JWS in JSON format streamed as <code>application/octet-stream</code>. Every key type writes the same flattened <code>{protected, signature}</code> document (RFC 7797, <code>\"b64\":false</code>, <code>\"crit\":[\"b64\"]</code>); only the header differs:<br> • SIMPLE keys: one signature, named by <code>kid</code> and <code>alg</code><br> • COMPOSITE keys: one composite signature (the ML-DSA and classical component signatures   in one value) over the RFC 7797 unencoded payload, under the protected header   <code>{alg, b64, crit, kid, ank_kv, iat}</code>: the composite <code>alg</code>, the   RFC 7797 members, <code>kid</code>, <code>ank_kv</code>, and <code>iat</code> whenever   this deployment's JWS local clock issues it. This operation takes no   <code>validityDays</code>, so the header carries no <code>exp</code>. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/sign-encrypt",
                "description": "Consumes a <code>multipart/form-data</code> request with a JSON <em>SignEncryptStreamRequest</em> metadata part ({signKid, encryptKid, validityDays?}) and a binary <code>file</code> part. The payload is signed with <code>signKid</code> and the resulting compact JWS is encrypted with <code>encryptKid</code>, so the signature is carried encrypted. <code>signKid</code> and <code>encryptKid</code> MUST be different. Each leg is dispatched by its own key, so every pairing of a symmetric, an asymmetric and a composite key is accepted - the nine sign-kind × encrypt-kind pairs, including a symmetric key on one leg and an asymmetric key on the other, and a composite key on either leg or both. What each key must be is the operation of its leg: <code>signKid</code> a key that signs (a composite signature key, never a composite KEM key) and <code>encryptKid</code> a key that encrypts (a composite KEM key, never a composite signature key); a key that does not support its leg's operation is 400 <code>invalid-input</code>, answered before any response byte. A composite <code>signKid</code> produces the same inner attached JWS a SIMPLE key does: one composite signature under one protected header <code>{alg, kid, ank_kv, iat[, exp]}</code>: <code>iat</code> whenever this deployment's JWS local clock issues it (<code>ankasecure.jws.local-clock.enabled</code> and <code>include-iat</code>, both on by default), and <code>exp</code> = <code>iat</code> + <code>validityDays</code> × 86400 when <code>validityDays</code> is sent. The response is the nested ciphertext streamed as <code>multipart/mixed</code> (JWE header + ciphertext). ",
                 "item": [
                            {
                                "name": "Sign-then-encrypt data (streaming, nested JWE(JWS)).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/sign-encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "sign-encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Consumes a <code>multipart/form-data</code> request with a JSON <em>SignEncryptStreamRequest</em> metadata part ({signKid, encryptKid, validityDays?}) and a binary <code>file</code> part. The payload is signed with <code>signKid</code> and the resulting compact JWS is encrypted with <code>encryptKid</code>, so the signature is carried encrypted. <code>signKid</code> and <code>encryptKid</code> MUST be different. Each leg is dispatched by its own key, so every pairing of a symmetric, an asymmetric and a composite key is accepted - the nine sign-kind × encrypt-kind pairs, including a symmetric key on one leg and an asymmetric key on the other, and a composite key on either leg or both. What each key must be is the operation of its leg: <code>signKid</code> a key that signs (a composite signature key, never a composite KEM key) and <code>encryptKid</code> a key that encrypts (a composite KEM key, never a composite signature key); a key that does not support its leg's operation is 400 <code>invalid-input</code>, answered before any response byte. A composite <code>signKid</code> produces the same inner attached JWS a SIMPLE key does: one composite signature under one protected header <code>{alg, kid, ank_kv, iat[, exp]}</code>: <code>iat</code> whenever this deployment's JWS local clock issues it (<code>ankasecure.jws.local-clock.enabled</code> and <code>include-iat</code>, both on by default), and <code>exp</code> = <code>iat</code> + <code>validityDays</code> × 86400 when <code>validityDays</code> is sent. The response is the nested ciphertext streamed as <code>multipart/mixed</code> (JWE header + ciphertext). "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/stream/verify",
                "description": "Two <code>multipart/form-data</code> parts: • <code>metadata</code> – JSON (<em>VerifyDetachedJwsStreamRequest</em>)   with a detached-JWS: the flattened <code>{protected, signature}</code> JSON   (RFC 7797, <code>\"b64\":false</code>, <code>\"crit\":[\"b64\"]</code>). • <code>file</code> – the binary payload originally signed. Extracts <code>kid</code> and <code>alg</code> from each signature's protected header, verifies, and returns a <em>VerifySignatureResponse</em> once the payload has been read.<br><br> Supports SIMPLE keys and COMPOSITE keys (one composite signature, named by <code>kid</code>, <code>ank_kv</code> and the composite <code>alg</code> in its protected header; valid only when both components verify).<br><br> <strong>A detached JWS signed by several keys</strong> is the General body <code>{\"signatures\":[{protected, signature}, ...]}</code> (RFC 7515 §7.2.1), each signature <code>b64:false</code> (RFC 7797). It is classified from its headers alone (422 for a root member besides <code>signatures</code>, a key named twice, an HMAC <code>alg</code>, or more signatures than the deployment admits; 400 when a signature does not declare the unencoded payload the others declare), then EVERY signer is gated — every VERIFY Capability Grant in token order, then every VERIFY key-lifecycle decision — before the <code>file</code> part is opened: a refusal is a 403 naming no key, with no verdict. The payload is then read ONCE into every signature, and <code>signatureResults</code> reports each signature's verdict, in token order; <code>valid</code> is true only when every one verifies.<br><br> <strong>Memory.</strong> The payload is read once, but what each signer's verification holds is its algorithm's: an ECDSA, RSA-PSS or ML-DSA signature, and every composite signature (which signs a pre-hash of the payload), keeps a fixed state while the payload streams; a pure EdDSA (Ed25519, Ed448), SLH-DSA or Falcon signature keeps the whole payload in memory until it is judged, because those schemes read the message more than once. A payload verified under k signers of those families is held k times. ",
                 "item": [
                            {
                                "name": "Verify a detached-JWS (streaming).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/stream/verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "stream",
        "verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Two <code>multipart/form-data</code> parts: • <code>metadata</code> – JSON (<em>VerifyDetachedJwsStreamRequest</em>)   with a detached-JWS: the flattened <code>{protected, signature}</code> JSON   (RFC 7797, <code>\"b64\":false</code>, <code>\"crit\":[\"b64\"]</code>). • <code>file</code> – the binary payload originally signed. Extracts <code>kid</code> and <code>alg</code> from each signature's protected header, verifies, and returns a <em>VerifySignatureResponse</em> once the payload has been read.<br><br> Supports SIMPLE keys and COMPOSITE keys (one composite signature, named by <code>kid</code>, <code>ank_kv</code> and the composite <code>alg</code> in its protected header; valid only when both components verify).<br><br> <strong>A detached JWS signed by several keys</strong> is the General body <code>{\"signatures\":[{protected, signature}, ...]}</code> (RFC 7515 §7.2.1), each signature <code>b64:false</code> (RFC 7797). It is classified from its headers alone (422 for a root member besides <code>signatures</code>, a key named twice, an HMAC <code>alg</code>, or more signatures than the deployment admits; 400 when a signature does not declare the unencoded payload the others declare), then EVERY signer is gated — every VERIFY Capability Grant in token order, then every VERIFY key-lifecycle decision — before the <code>file</code> part is opened: a refusal is a 403 naming no key, with no verdict. The payload is then read ONCE into every signature, and <code>signatureResults</code> reports each signature's verdict, in token order; <code>valid</code> is true only when every one verifies.<br><br> <strong>Memory.</strong> The payload is read once, but what each signer's verification holds is its algorithm's: an ECDSA, RSA-PSS or ML-DSA signature, and every composite signature (which signs a pre-hash of the payload), keeps a fixed state while the payload streams; a pure EdDSA (Ed25519, Ed448), SLH-DSA or Falcon signature keeps the whole payload in memory until it is judged, because those schemes read the message more than once. A payload verified under k signers of those families is held k times. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": " Secure",
	            "description": "Endpoints to manage and perform cryptographic operations with symmetric\nand post-quantum/classical asymmetric keys (AES, RSA, ECC, ML-KEM, ML-DSA, Falcon, etc.).\n",
	            "item": [
	                        {
    "name": "/api/v3/crypto/decrypt",
                "description": "Parses and decrypts the given JWE using the private key it is addressed to. Returns the plaintext (Base64-encoded) plus metadata about key selection, algorithm, and any warnings.  Uses JWE General JSON Serialization (RFC 7516 §7.2) uniformly — single-recipient for SIMPLE keys, one recipient per component for COMPOSITE hybrid keys (the key named by the <code>kid</code> in <code>protected</code>), and one recipient per key for a JWE addressed to several keys (each recipient naming its key in its own header, no <code>kid</code> in <code>protected</code>).  <b>A JWE addressed to several keys is decrypted with the ONE recipient the caller names</b> in <code>recipientKid</code> (RFC 7516 §5.2 leaves that choice to the application). In this order, each step before the next: the token is classified from its public headers alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the member and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) — a refusal is the generic 403, which names no key; a composite key as the named recipient is refused (422); and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. <code>keyRequested</code> and <code>materialVersion</code> report the named recipient. ",
                 "item": [
                            {
                                "name": "SIMPLE key (single-recipient General JSON)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoibXktcnNhLTMwNzIta2V5IiwidmVyIjoiMi4wIiwiYW5rX2t2IjoxfQ\",\n    \"recipients\" : [ {\n      \"encrypted_key\" : \"OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9k\"\n    } ],\n    \"iv\" : \"48V1_ALb6US04U3b\",\n    \"ciphertext\" : \"5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4\",\n    \"tag\" : \"XFBoMYUZodetZdvTiFvSkQ\"\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/decrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "decrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Parses and decrypts the given JWE using the private key it is addressed to. Returns the plaintext (Base64-encoded) plus metadata about key selection, algorithm, and any warnings.  Uses JWE General JSON Serialization (RFC 7516 §7.2) uniformly — single-recipient for SIMPLE keys, one recipient per component for COMPOSITE hybrid keys (the key named by the <code>kid</code> in <code>protected</code>), and one recipient per key for a JWE addressed to several keys (each recipient naming its key in its own header, no <code>kid</code> in <code>protected</code>).  <b>A JWE addressed to several keys is decrypted with the ONE recipient the caller names</b> in <code>recipientKid</code> (RFC 7516 §5.2 leaves that choice to the application). In this order, each step before the next: the token is classified from its public headers alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the member and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) — a refusal is the generic 403, which names no key; a composite key as the named recipient is refused (422); and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. <code>keyRequested</code> and <code>materialVersion</code> report the named recipient. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Recipient 2 of 3 named",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJlbmMiOiJBMjU2R0NNIiwidmVyIjoiMi4wIiwiYW5rX2t2cyI6eyJhY21lLWFyY2hpdmUtcjEiOjEsImFjbWUtYXJjaGl2ZS1yMiI6NCwiYWNtZS1hcmNoaXZlLXIzIjoyfX0\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r1\"\n      },\n      \"encrypted_key\" : \"QVpxc0ZnWmxDbjdXUE1qV3lVaFp2aEtUcEt3cWxHWkxUMnF6\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r2\"\n      },\n      \"encrypted_key\" : \"dW5Qc1BTa3pVZ2RVZ0FjY2hRTVh6Q0dSb2tYbkpNZ2xTbHNE\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r3\"\n      },\n      \"encrypted_key\" : \"a2pYc0lFVk5xQ3dtRmVhVnJ5YW9EV2l6cG5Ic0tQUmJ1VmJk\"\n    } ],\n    \"iv\" : \"yv66vvrO263eyviI\",\n    \"ciphertext\" : \"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY\",\n    \"tag\" : \"Mz-VPPyU4RlcuYv1IwIvzw\"\n  },\n  \"recipientKid\" : \"acme-archive-r2\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/decrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "decrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Parses and decrypts the given JWE using the private key it is addressed to. Returns the plaintext (Base64-encoded) plus metadata about key selection, algorithm, and any warnings.  Uses JWE General JSON Serialization (RFC 7516 §7.2) uniformly — single-recipient for SIMPLE keys, one recipient per component for COMPOSITE hybrid keys (the key named by the <code>kid</code> in <code>protected</code>), and one recipient per key for a JWE addressed to several keys (each recipient naming its key in its own header, no <code>kid</code> in <code>protected</code>).  <b>A JWE addressed to several keys is decrypted with the ONE recipient the caller names</b> in <code>recipientKid</code> (RFC 7516 §5.2 leaves that choice to the application). In this order, each step before the next: the token is classified from its public headers alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the member and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) — a refusal is the generic 403, which names no key; a composite key as the named recipient is refused (422); and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. <code>keyRequested</code> and <code>materialVersion</code> report the named recipient. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE hybrid key (multi-recipient General JSON)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJlbmMiOiJBMjU2R0NNIiwia2lkIjoibXktaHlicmlkLWtleSIsInR5cCI6IkpPU0UiLCJhbmtfa3YiOjEsImFua2Ffa2RmIjoiSEtERi1TSEEyNTYifQ\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"alg\" : \"X25519\"\n      },\n      \"encrypted_key\" : \"nOOwTl-KlxS4C3zPRZE7AOBrq4phR7gy1pbmgWYZDQI\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"ML-KEM-768\"\n      },\n      \"encrypted_key\" : \"m20tVVdqBXnyjcdPW3w2E0sD9vxsF4Vqf9bt2guenEXUW_k12AsYrRAX3PudXN4YLi18MjfyJbq3CP0z7PwU8DcFabBuBLmjCT-Bv8EGIMRfkEPBuw9wUxjy8uwCn2u0Lwvcl2h8GSRq1edvHpSE71y1la3ObZT7w-PbAnbgyOQapHyoJpQS8O11hXQiKNbICH3WSYDIZztVYD-o5YsH9Ra6VbX5WZycF3r8rD1oSz5YV7K_qMWXUkiDF_g2jNdagK7cShPkn_Fx1TvVj9mX2RqVbB99xduyYRNiD1zq4DlJnI07r792AXONOvN-KmZaSqoM9qgfpEezA55H24j9-MIb4D8lBReWXnap3lbgcHQyLPsZ9N3dTGGDjIgGb6y8gBxPEK8wd1w2-GX-rF0NhNKr7Md1c7CST6cCkCG1TX9fhQv6yWx1hNIJVZ3irB3Qsdt2W6IZvacdrk0KTD_sD0tahNF6nWPd3P0lgoieHhGtcgZnoHPtw5ZVEbUpMpkLMMFb8W1JNXcosTWG8RfKxiVKI3H9vA3AWHNn7yuuQg02FSqfhoF6O_OdX4pk9NMoGN45w4sCVTWRi786la_g75oHKfdQUETHZVYApZiw9movE-sqhlRfwtma3mRU1nd6UTUYNPGbkzeqFR7fzy8R1UCjrd91zs4PeXnBzMSnYkRsvSnD9Ww6yY2ztqUdzDADIwpVOIbDku_1NKF5B2TF4_sZCojwLsXVSqirJqlw21k_qld7870MtzCzVFsYPo2c2W-z0xXLkY2hAluWfd_FtHZII0y3mgGCPc5Pomg-rupRd8zw_x173uPbCLshZdsjFRkW4dIUr9DKeTxkGpCKuC5MzT1Ww2KojPH442h3BbEO58XPM__hkl_Ii32x9mD97SbVc4U0s_caP5L3PMjFVbMi8waGBd6PumbSPiqOEC7e31v5PoRaA8_qQCv2AkbLMCRBWpWvYXe0DZqnqrV16wQhtKgafFwTF5qOiVy6RlgFneVuynzUG8m4xycyGGqplwjv4mqg89RmK6ER8Oey2WS9WtXIOVrX92RLLqR6Wt0gwqp5XduaRQy17VFn4V-iLmeBDnXp8RIFFC-OCG5UcT6gDwufKU5MyTqYe6cncjj1fg-F8HgpD62ZbUjOitqpHUKGaTGKbvqRVrja0xLx2vrXf6TWiY4Qlv1zKhEAkXvsNzSW7F-zZHxATfOvX6Wb_EdQFTCGuatw2KyJHnlaEOO-sBqnRGgST6pb7x3Xw8DskgJEgOpdXeK86DFQcLnJnaonmVnJkimtgpOob9459LI86GhhrFV4xCfK06Sn60MHKDypZKy6-WxDQWYepiYZaORhtC4QdC2ijtZVgHt-oXu0e1vsvhemO5-qMDxR3CzzzfqRfOjfLA4EPC64iHDk7Fspj2-6I-7Jq4HOuP4H-0gNvPiZFqJ_K1Tzxy_aUaQ\"\n    } ],\n    \"iv\" : \"e4j0J1JjR_sUyd38\",\n    \"ciphertext\" : \"fwjaJQF0rRAwYw\",\n    \"tag\" : \"xVbiloc3YU5aI3fl63-BRw\"\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/decrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "decrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Parses and decrypts the given JWE using the private key it is addressed to. Returns the plaintext (Base64-encoded) plus metadata about key selection, algorithm, and any warnings.  Uses JWE General JSON Serialization (RFC 7516 §7.2) uniformly — single-recipient for SIMPLE keys, one recipient per component for COMPOSITE hybrid keys (the key named by the <code>kid</code> in <code>protected</code>), and one recipient per key for a JWE addressed to several keys (each recipient naming its key in its own header, no <code>kid</code> in <code>protected</code>).  <b>A JWE addressed to several keys is decrypted with the ONE recipient the caller names</b> in <code>recipientKid</code> (RFC 7516 §5.2 leaves that choice to the application). In this order, each step before the next: the token is classified from its public headers alone (422, or 400 for a member name in both <code>protected</code> and a recipient header); <code>recipientKid</code> must name one of its recipients (400 naming the member and no key); ONE Capability Grant decision for DECRYPT and ONE key-lifecycle decision are taken on that key only, at the material version the integrity-protected <code>ank_kvs</code> records for it (the PRIMARY when it records none) — a refusal is the generic 403, which names no key; a composite key as the named recipient is refused (422); and only that recipient's <code>encrypted_key</code> is unwrapped. No other recipient is ever gated, resolved or tried, and there is no fallback after a refusal or an unwrap failure. <code>keyRequested</code> and <code>materialVersion</code> report the named recipient. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/decrypt-verify",
                "description": "Performs decrypt-then-verify operation: decrypts nested JWE to reveal inner JWS, then verifies the signature and extracts original plaintext.  The decrypting key is the outer JWE's own key; for a JWE addressed to several keys it is the ONE recipient `recipientKid` names, decided by one DECRYPT grant and one lifecycle decision before anything is unwrapped. Every signer of the inner JWS is read from its own protected header (RFC 7515 §7.2.1), passes its VERIFY grant and lifecycle for the caller, and is verified under its own key; `signatureResults` reports each one. The plaintext is returned only when every inner signature verifies, and the decrypting key must be none of the inner signers.  COMPOSITE keys are supported via JWE/JWS General JSON Serialization format.  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, read at the material version its own header names, exactly as on the streaming `/api/v3/crypto/stream/decrypt-verify`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE decryption key with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE verification key — for example ML-KEM-768 + HMAC-SHA256, AES-GCM-256 + ML-DSA-65, or COMPOSITE_KEM_COMBINE + COMPOSITE_SIGNATURE. A key of the wrong kind for its leg is refused **400** `invalid-input`, and no plaintext is returned.  A token addressed to, or signed by, several keys is verified one signature at a time, each dispatched by its own key; the key pairs below are those of a single recipient and a single inner signer.  Returns 422 if signature verification fails or token format is invalid. ",
                 "item": [
                            {
                                "name": "SIMPLE keys (single-recipient General JSON)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJhbGciOiJNTC1LRU0tMTAyNCIsImVuYyI6IkEyNTZHQ00iLCJjdHkiOiJKV1MiLCJraWQiOiJteS1kZWNyeXB0LWtleSJ9\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"kid\" : \"my-decrypt-key\"\n      },\n      \"encrypted_key\" : \"EncryptedKey_BASE64URL\"\n    } ],\n    \"iv\" : \"IV_BASE64URL\",\n    \"ciphertext\" : \"InnerJwsCiphertext_BASE64URL\",\n    \"tag\" : \"Tag_BASE64URL\"\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/decrypt-verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "decrypt-verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Performs decrypt-then-verify operation: decrypts nested JWE to reveal inner JWS, then verifies the signature and extracts original plaintext.  The decrypting key is the outer JWE's own key; for a JWE addressed to several keys it is the ONE recipient `recipientKid` names, decided by one DECRYPT grant and one lifecycle decision before anything is unwrapped. Every signer of the inner JWS is read from its own protected header (RFC 7515 §7.2.1), passes its VERIFY grant and lifecycle for the caller, and is verified under its own key; `signatureResults` reports each one. The plaintext is returned only when every inner signature verifies, and the decrypting key must be none of the inner signers.  COMPOSITE keys are supported via JWE/JWS General JSON Serialization format.  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, read at the material version its own header names, exactly as on the streaming `/api/v3/crypto/stream/decrypt-verify`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE decryption key with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE verification key — for example ML-KEM-768 + HMAC-SHA256, AES-GCM-256 + ML-DSA-65, or COMPOSITE_KEM_COMBINE + COMPOSITE_SIGNATURE. A key of the wrong kind for its leg is refused **400** `invalid-input`, and no plaintext is returned.  A token addressed to, or signed by, several keys is verified one signature at a time, each dispatched by its own key; the key pairs below are those of a single recipient and a single inner signer.  Returns 422 if signature verification fails or token format is invalid. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE hybrid keys (multi-recipient General JSON)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJlbmMiOiJBMjU2R0NNIiwia2lkIjoibXktaHlicmlkLWRlY3J5cHQta2V5IiwidHlwIjoiSk9TRSIsImFua19rdiI6MSwiYW5rYV9rZGYiOiJIS0RGLVNIQTI1NiJ9\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"alg\" : \"X25519\"\n      },\n      \"encrypted_key\" : \"SyJuz7p1lAVPfQV420q07TZFOokvQ3zYQcrz0MYixF0\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"ML-KEM-768\"\n      },\n      \"encrypted_key\" : \"nDWQr4L03SsECvjZGtt0ZQu8seqeEHcJZk9Up7X1agoi8LWFZtGDOEU8w2LiDFcrvYoj4XYv1o1jHVAj11ezzEXQPned4qoxtF2o53P_5gnRjJ70Wmvizdiszv_zQwRj8lJiMbjV3SZucB1rxeXf4Py1Y0SdVXbZzSLf_xHcKDP7KyKUFwt5-YRKD2Dcx2enOal3GPhdw0_dhxPb1GXOJ8RXLBiCFF6dZOXM9mFn-VUn30rqazY1uz_i_8aCoaYSiHQ6k6nH9uMhfMORTD69HhTU9yrOXYJtgbd52msJOceGNmA5tzH3vCzqIVVhc5dfNHsgRp7Pen49oolc33kJUHhtOndKJyHI2v1EwBqeI8D7dffhFrZHm8clhTfnjkYiBDO8b2N4fCH4hGL1DlEMcHlUF5i8nWfPEogGsUnRTAvSJeRTyRbeURT58K4HDXj1Ov2ZFbpm1IEad_k-P3HAuib_zZknx9gS9RzcCaptIk1ETreLLTkg4dHUE1SJ2PfSuuxybO-06UbPZxboWYHhLaQ3ZsFhk9W9P9sj6xF6civPGCvgWQA5NF08pMMrGgjrmd2sJgA-u732BwxOWO_W_lsWNB-s5c-vAqiNNAT5wUELNX7CU_8dZVbeIMUnXJxxqR2MF4WW7ea729QrmwwObPISSYAPUR1iVVpwmP0b5PwpLKaEbgUGevW6yYK5WuvEoHpFWRupvsbibZkMO0fVdUcaUUh_12YjyLT2fJiPQVft2QZYxYbQXYqW-He1qZ7rl1clXEXaQGcJYL55sfY22J4yjYX5EeOgpyKr7M8_YM8F6R6Aku85ejlgt0MFkSoEw0x7at1Dde60W0YZK-lDE4DGhwv_e5Pp0Vfe04bwnyuAaBzWm90xrRXfplda6UbBibfw2VBbQx7rT2p0TpL2yqETTuYRj6nmfksUdv4HE_hdzlJMr172yWUHlE3IKkzU6hM-wsFp4Xc4QM5G9PusAQ474BxNeQu4g90aLiHp8iYC4EjBSABRrTZuNb67yvfnogG0iUayHL_b96QFuWx46teASs2Iae2gR18kS0tO2-aGE0GMZLSt1JKyn3acCpsWB01PLJq9Kojf056KywjzRtoxsKaEmnIWQjAqnR9j4GPGy-ipsRFnZNfWfkfSaCm6_cknl2CxDRXv0xh5di0opKk-6-cDa1cSpg6r9lOXBBt_JeN3Y1LMcEclrQgp4IDogOF3jku9hZnerk-S6r8FlrbdNzlF2VqiTgInUordo_v1Dm0chtfMn4Mj94HV504lP13zv_OfUjqbtlsIOARYias-EXYvGwDQzc3VDgMIDQkUHUXqWi9IYCSUEiNkSL4gKnDjjYEOXJ-r22QpPLnzOqNgitqLtlmN6LsrjdcLMf2dfBqlK2YixCN_gh9-S4rRF0gGAsFJQL2h4OzvSSQoEKmqQUSb68qX-ZKI2L1bvTE\"\n    } ],\n    \"iv\" : \"HkhZtfl5YrzWnNNC\",\n    \"ciphertext\" : \"IQ_So8jdWxyak_HSMcVJVPsRCXuMMTTPZwCxh4ahyBEvqMN-1kNMuChHV-k1-96WwL8kXf7JbVtUbt_3IgrmW16fTC9ZZ9wOvP2fKPp9POlibIuR8TF7UNu1rwT38_YN5DSSjwnqu9YapwOkRjueQHKIVk-LQUpaT9ndEaQZfvn7D9cF3nnGg7_Kj79znzmzF-7HxXbgkOB0AGPKuo3d9Zg-jg9jIpTHdo6DFdRe54HQEvPDH1OiH0g1-pbSIBl93fpDo-021FKgP6Y5kipSYP0BmfXLgkfORhR1kvLF48hXq53COAUMjFFBMTkbqlvJSWFFkASXhaCm0Haj4DYaVUaOLdXFGW3Vk3x2Hvn2p-usUdAYa6QQSpN984bqnuEiSxBgM_wKVpiWgrWR4aYPV2eu3cAS8BDBQ9aKEWJMh1vNrlAwq8GyPAe-61auFzlyEMiPuKi6\",\n    \"tag\" : \"dQpPYl3LKEmyuf3h-G60FA\"\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/decrypt-verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "decrypt-verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Performs decrypt-then-verify operation: decrypts nested JWE to reveal inner JWS, then verifies the signature and extracts original plaintext.  The decrypting key is the outer JWE's own key; for a JWE addressed to several keys it is the ONE recipient `recipientKid` names, decided by one DECRYPT grant and one lifecycle decision before anything is unwrapped. Every signer of the inner JWS is read from its own protected header (RFC 7515 §7.2.1), passes its VERIFY grant and lifecycle for the caller, and is verified under its own key; `signatureResults` reports each one. The plaintext is returned only when every inner signature verifies, and the decrypting key must be none of the inner signers.  COMPOSITE keys are supported via JWE/JWS General JSON Serialization format.  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, read at the material version its own header names, exactly as on the streaming `/api/v3/crypto/stream/decrypt-verify`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE decryption key with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE verification key — for example ML-KEM-768 + HMAC-SHA256, AES-GCM-256 + ML-DSA-65, or COMPOSITE_KEM_COMBINE + COMPOSITE_SIGNATURE. A key of the wrong kind for its leg is refused **400** `invalid-input`, and no plaintext is returned.  A token addressed to, or signed by, several keys is verified one signature at a time, each dispatched by its own key; the key pairs below are those of a single recipient and a single inner signer.  Returns 422 if signature verification fails or token format is invalid. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/encrypt",
                "description": "Encrypts Base64‑encoded data using the <em>public key</em> associated with <code>kid</code>. Supported algorithms: ML‑KEM (KEM), RSA, ECC (ECIES).  Output: a typed JWE General JSON Serialization (RFC 7516 §7.2) payload — uniform shape across SIMPLE single-recipient keys and COMPOSITE hybrid multi-recipient keys. ",
                 "item": [
                            {
                                "name": "Encrypt request",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"kid\" : \"myKeyKid\",\n  \"data\" : \"SGVsbG8gQW5rYQ==\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Encrypts Base64‑encoded data using the <em>public key</em> associated with <code>kid</code>. Supported algorithms: ML‑KEM (KEM), RSA, ECC (ECIES).  Output: a typed JWE General JSON Serialization (RFC 7516 §7.2) payload — uniform shape across SIMPLE single-recipient keys and COMPOSITE hybrid multi-recipient keys. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/reencrypt",
                "description": "Decrypts the incoming JWE and re-encrypts the plaintext under a <strong>fresh</strong> content-encryption key for <code>newKid</code>. The result is a fresh JWE General JSON Serialization (RFC 7516 §7.2) payload — single-recipient for SIMPLE target keys, multi-recipient for COMPOSITE hybrid targets.  **Which key is replaced — <code>sourceKid</code>.** For a JWE that names one key (its <code>kid</code>), <code>sourceKid</code> is optional and, present, must equal it. For a JWE that names no key, <code>sourceKid</code> names the key it was produced for. For a JWE addressed to several keys (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>), it is required and names the ONE recipient replaced: only that recipient's <code>encrypted_key</code> is unwrapped, and no recipient is ever tried in its place.  **A JWE addressed to several keys.** The output keeps every other recipient in its position and puts <code>newKid</code> at the replaced one. Because one content-encryption key is shared by every recipient (RFC 7516 §7.2.1), a new one is always drawn: the replaced key cannot read the output. Every kept recipient is re-wrapped at its current PRIMARY, which the output's protected <code>ank_kvs</code> records and <code>recipients[]</code> of the response reports. Authorisation follows the flow of the content, as AWS KMS <code>ReEncrypt</code> does with <code>ReEncryptFrom</code>/<code>ReEncryptTo</code>: the caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> AND from the replaced key to every kept recipient — and no <code>DECRYPT</code> grant on any key, so re-encryption grants no access to the plaintext. Every grant is decided in recipient order, then every key-lifecycle decision (the replaced key on the DECRYPT row, <code>newKid</code> on the REENCRYPT row, each kept recipient on the ENCRYPT row), all before any key material is used. A recipient entry is not integrity-protected (only the protected header is): a JWE whose recipients are not exactly the set its protected header records is refused, so no entry added to a token can receive its content. ",
                 "item": [
                            {
                                "name": "SIMPLE → SIMPLE re-encryption",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoib2xkLXJzYS1rZXkiLCJ2ZXIiOiIyLjAiLCJhbmtfa3YiOjF9\",\n    \"recipients\" : [ {\n      \"encrypted_key\" : \"OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9k\"\n    } ],\n    \"iv\" : \"48V1_ALb6US04U3b\",\n    \"ciphertext\" : \"5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4\",\n    \"tag\" : \"XFBoMYUZodetZdvTiFvSkQ\"\n  },\n  \"newKid\" : \"new-mlkem-key\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/reencrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "reencrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Decrypts the incoming JWE and re-encrypts the plaintext under a <strong>fresh</strong> content-encryption key for <code>newKid</code>. The result is a fresh JWE General JSON Serialization (RFC 7516 §7.2) payload — single-recipient for SIMPLE target keys, multi-recipient for COMPOSITE hybrid targets.  **Which key is replaced — <code>sourceKid</code>.** For a JWE that names one key (its <code>kid</code>), <code>sourceKid</code> is optional and, present, must equal it. For a JWE that names no key, <code>sourceKid</code> names the key it was produced for. For a JWE addressed to several keys (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>), it is required and names the ONE recipient replaced: only that recipient's <code>encrypted_key</code> is unwrapped, and no recipient is ever tried in its place.  **A JWE addressed to several keys.** The output keeps every other recipient in its position and puts <code>newKid</code> at the replaced one. Because one content-encryption key is shared by every recipient (RFC 7516 §7.2.1), a new one is always drawn: the replaced key cannot read the output. Every kept recipient is re-wrapped at its current PRIMARY, which the output's protected <code>ank_kvs</code> records and <code>recipients[]</code> of the response reports. Authorisation follows the flow of the content, as AWS KMS <code>ReEncrypt</code> does with <code>ReEncryptFrom</code>/<code>ReEncryptTo</code>: the caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> AND from the replaced key to every kept recipient — and no <code>DECRYPT</code> grant on any key, so re-encryption grants no access to the plaintext. Every grant is decided in recipient order, then every key-lifecycle decision (the replaced key on the DECRYPT row, <code>newKid</code> on the REENCRYPT row, each kept recipient on the ENCRYPT row), all before any key material is used. A recipient entry is not integrity-protected (only the protected header is): a JWE whose recipients are not exactly the set its protected header records is refused, so no entry added to a token can receive its content. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE → COMPOSITE re-encryption (hybrid PQC rotation)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJlbmMiOiJBMjU2R0NNIiwia2lkIjoib2xkLWh5YnJpZC1rZXkiLCJ0eXAiOiJKT1NFIiwiYW5rX2t2IjoxLCJhbmthX2tkZiI6IkhLREYtU0hBMjU2In0\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"alg\" : \"X25519\"\n      },\n      \"encrypted_key\" : \"b30bG_ngCxu8BHsDepgrtjbnj_gXqb_BzluB3A9ebw0\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"ML-KEM-768\"\n      },\n      \"encrypted_key\" : \"LGP9JsZ-Cn83kxvIrTAlxqyRyEPcSyMywdAS5nQJfk2m_QiFgraznRN1JSU6TwxDlcPnoUc6mHABPS9PitfsqHBd00eYBaYjTo7gmjDWtaWXrt6Vqn7sSG5LeT3JdDIuyOuk6N4to3gLyMmfowsNnSqYXWFRysGHBXVQrbXZo0l9qf0yaMztmKUop-XpXiaDt2OxU5nB3FDWngARATHhMSWFjpPvr4F9HIVQMY8ED1q8lJdMTpj2qOOdJQEkeKvee_KE33gw81P7Vn916oI1KT8P6aTr3rtXxFU8GUDtQb-NuJX2Jo2ppsAdvD6crM8pgcTMU-7cY09_dpPM2qf_ieQoJ6NLMYelD-vtfbVzGKm_sL_FrrviiZNxalhQRFenDtlWbB1lOWco70nhe6CX_QMNuKq9Y19pj6gTow3OorpB9Uc0voU0h-P_e5icx2t-lt6a_x6cEB6481wOtPxKIS0zoC392d9Ln3hUsMl7EQx-yY8-n--loiBiKnOilfEUaDR1MifTysJo1LlofOj9qLWhtvSOpd5b7Or2VAkjfrAvUkcrP3rcmKtz823ayIfmiPjf-bd95n4_cgKGUHaYKEAg8a7AAQPbDH8SjhYOde1EiPoqnVekNEX3zigiloQ4mlla0780xJO4zmrjIwn1ahnACh5DmtSu9ccwg6jsVtVo_T6kwx-QuRwpTOz2bYGTg0eql3bihClVCfJqzFf07LXEQeakigHCGaHuEGtCnl3ACah5KlCsht9D3W8ie09cEhOjEHtkXPCL46gG0hyK7YWusrpwBGKGO5L4_BsDspyd1V_9QnP8FsFK9335bnOOX9ZmV3tNmsvgsvvtYC6AsH-4lkVfzxZIvvIWCiGNNpcx9GsVJggEUOucUeIzhw19QkrSBRu2XlQ1A4PoYluW_6BDUF7QTBso38WtU7NqS75A-xL2MbCvRrJLetn5AxpifgzN2YpR6z-R4M8OKn8YZ1ERiHF2cpeVNGqM_ASq-ZhgBRa9aBkwIHOwMfqjfCcNk_AF7o_9e61Cd4v9KxfUGuN2T6i9qFSDCsCmnhhyEgY3p7WPZ8t6XHQgQ6btSeDUbQxY5ETmvXMVY-d1vLfzXRJHNzGSeFpWJnOTdEEeuZqC65jV45plpyWL5DpjZmr916t68YsRmIRDTlG9um49kxAP_mlzmDcTvAZILwBUlf9pOu9bGxFoLTXY5OQPqAhaonoEPQJR1GcvbZadXib84GWnVnvP6G_FntB9qzj0Q6vemLxdvle6D0mrI0XZI2WRvfwxIx5bGE5j5hu6XIKxU6hKfJej-dTjC4GcorsaO9KK_Cji2NhKf-NDwe4jMW_sPBRWe_SdpcE0pPx9vr4oMnB9dRE5Wr2iS7untej5WRDOSf2YvqiaMWafcfaEFfDcq_6aT3qGvxUPV0uiCt0h-dO7OSNQtlQkI5Meh0vd1po\"\n    } ],\n    \"iv\" : \"aWQ1_9E0plxSVj_f\",\n    \"ciphertext\" : \"wujOsY13uvBOcA\",\n    \"tag\" : \"QH1mh28lTnKN1wXQAthkDg\"\n  },\n  \"newKid\" : \"new-hybrid-key\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/reencrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "reencrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Decrypts the incoming JWE and re-encrypts the plaintext under a <strong>fresh</strong> content-encryption key for <code>newKid</code>. The result is a fresh JWE General JSON Serialization (RFC 7516 §7.2) payload — single-recipient for SIMPLE target keys, multi-recipient for COMPOSITE hybrid targets.  **Which key is replaced — <code>sourceKid</code>.** For a JWE that names one key (its <code>kid</code>), <code>sourceKid</code> is optional and, present, must equal it. For a JWE that names no key, <code>sourceKid</code> names the key it was produced for. For a JWE addressed to several keys (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>), it is required and names the ONE recipient replaced: only that recipient's <code>encrypted_key</code> is unwrapped, and no recipient is ever tried in its place.  **A JWE addressed to several keys.** The output keeps every other recipient in its position and puts <code>newKid</code> at the replaced one. Because one content-encryption key is shared by every recipient (RFC 7516 §7.2.1), a new one is always drawn: the replaced key cannot read the output. Every kept recipient is re-wrapped at its current PRIMARY, which the output's protected <code>ank_kvs</code> records and <code>recipients[]</code> of the response reports. Authorisation follows the flow of the content, as AWS KMS <code>ReEncrypt</code> does with <code>ReEncryptFrom</code>/<code>ReEncryptTo</code>: the caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> AND from the replaced key to every kept recipient — and no <code>DECRYPT</code> grant on any key, so re-encryption grants no access to the plaintext. Every grant is decided in recipient order, then every key-lifecycle decision (the replaced key on the DECRYPT row, <code>newKid</code> on the REENCRYPT row, each kept recipient on the ENCRYPT row), all before any key material is used. A recipient entry is not integrity-protected (only the protected header is): a JWE whose recipients are not exactly the set its protected header records is refused, so no entry added to a token can receive its content. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Header names no key: sourceKid supplies it",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIn0\",\n    \"recipients\" : [ {\n      \"header\" : { },\n      \"encrypted_key\" : \"Q2tXdHNPR3VaUjNKZ1BKcE5mV0RoYlhVdVpxQkZpbHNCa0Rr\"\n    } ],\n    \"iv\" : \"Zm9vYmFyYmF6cXV4\",\n    \"ciphertext\" : \"U2VjcmV0IGFyY2hpdmUgbWFuaWZlc3Q\",\n    \"tag\" : \"d3JhcHBlZC10YWctMTY\"\n  },\n  \"newKid\" : \"new-mlkem-key\",\n  \"sourceKid\" : \"legacy-rsa-key\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/reencrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "reencrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Decrypts the incoming JWE and re-encrypts the plaintext under a <strong>fresh</strong> content-encryption key for <code>newKid</code>. The result is a fresh JWE General JSON Serialization (RFC 7516 §7.2) payload — single-recipient for SIMPLE target keys, multi-recipient for COMPOSITE hybrid targets.  **Which key is replaced — <code>sourceKid</code>.** For a JWE that names one key (its <code>kid</code>), <code>sourceKid</code> is optional and, present, must equal it. For a JWE that names no key, <code>sourceKid</code> names the key it was produced for. For a JWE addressed to several keys (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>), it is required and names the ONE recipient replaced: only that recipient's <code>encrypted_key</code> is unwrapped, and no recipient is ever tried in its place.  **A JWE addressed to several keys.** The output keeps every other recipient in its position and puts <code>newKid</code> at the replaced one. Because one content-encryption key is shared by every recipient (RFC 7516 §7.2.1), a new one is always drawn: the replaced key cannot read the output. Every kept recipient is re-wrapped at its current PRIMARY, which the output's protected <code>ank_kvs</code> records and <code>recipients[]</code> of the response reports. Authorisation follows the flow of the content, as AWS KMS <code>ReEncrypt</code> does with <code>ReEncryptFrom</code>/<code>ReEncryptTo</code>: the caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> AND from the replaced key to every kept recipient — and no <code>DECRYPT</code> grant on any key, so re-encryption grants no access to the plaintext. Every grant is decided in recipient order, then every key-lifecycle decision (the replaced key on the DECRYPT row, <code>newKid</code> on the REENCRYPT row, each kept recipient on the ENCRYPT row), all before any key material is used. A recipient entry is not integrity-protected (only the protected header is): a JWE whose recipients are not exactly the set its protected header records is refused, so no entry added to a token can receive its content. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Recipient 2 of 3 replaced",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jweToken\" : {\n    \"protected\" : \"eyJlbmMiOiJBMjU2R0NNIiwidmVyIjoiMi4wIiwiYW5rX2t2cyI6eyJhY21lLWFyY2hpdmUtcjEiOjEsImFjbWUtYXJjaGl2ZS1yMiI6NCwiYWNtZS1hcmNoaXZlLXIzIjoyfX0\",\n    \"recipients\" : [ {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r1\"\n      },\n      \"encrypted_key\" : \"QVpxc0ZnWmxDbjdXUE1qV3lVaFp2aEtUcEt3cWxHWkxUMnF6\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r2\"\n      },\n      \"encrypted_key\" : \"dW5Qc1BTa3pVZ2RVZ0FjY2hRTVh6Q0dSb2tYbkpNZ2xTbHNE\"\n    }, {\n      \"header\" : {\n        \"alg\" : \"RSA-OAEP-512\",\n        \"kid\" : \"acme-archive-r3\"\n      },\n      \"encrypted_key\" : \"a2pYc0lFVk5xQ3dtRmVhVnJ5YW9EV2l6cG5Ic0tQUmJ1VmJk\"\n    } ],\n    \"iv\" : \"yv66vvrO263eyviI\",\n    \"ciphertext\" : \"KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY\",\n    \"tag\" : \"Mz-VPPyU4RlcuYv1IwIvzw\"\n  },\n  \"sourceKid\" : \"acme-archive-r2\",\n  \"newKid\" : \"acme-archive-r4\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/reencrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "reencrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Decrypts the incoming JWE and re-encrypts the plaintext under a <strong>fresh</strong> content-encryption key for <code>newKid</code>. The result is a fresh JWE General JSON Serialization (RFC 7516 §7.2) payload — single-recipient for SIMPLE target keys, multi-recipient for COMPOSITE hybrid targets.  **Which key is replaced — <code>sourceKid</code>.** For a JWE that names one key (its <code>kid</code>), <code>sourceKid</code> is optional and, present, must equal it. For a JWE that names no key, <code>sourceKid</code> names the key it was produced for. For a JWE addressed to several keys (no <code>kid</code> in <code>protected</code>, a <code>kid</code> in every recipient header, the recipient set recorded in the protected <code>ank_kvs</code>), it is required and names the ONE recipient replaced: only that recipient's <code>encrypted_key</code> is unwrapped, and no recipient is ever tried in its place.  **A JWE addressed to several keys.** The output keeps every other recipient in its position and puts <code>newKid</code> at the replaced one. Because one content-encryption key is shared by every recipient (RFC 7516 §7.2.1), a new one is always drawn: the replaced key cannot read the output. Every kept recipient is re-wrapped at its current PRIMARY, which the output's protected <code>ank_kvs</code> records and <code>recipients[]</code> of the response reports. Authorisation follows the flow of the content, as AWS KMS <code>ReEncrypt</code> does with <code>ReEncryptFrom</code>/<code>ReEncryptTo</code>: the caller needs a Capability Grant for <code>REENCRYPT</code> from the replaced key to <code>newKid</code> AND from the replaced key to every kept recipient — and no <code>DECRYPT</code> grant on any key, so re-encryption grants no access to the plaintext. Every grant is decided in recipient order, then every key-lifecycle decision (the replaced key on the DECRYPT row, <code>newKid</code> on the REENCRYPT row, each kept recipient on the ENCRYPT row), all before any key material is used. A recipient entry is not integrity-protected (only the protected header is): a JWE whose recipients are not exactly the set its protected header records is refused, so no entry added to a token can receive its content. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/resign",
                "description": "Verifies the incoming JWS (Compact or General JSON Serialization) under its embedded `oldKid` (or the key `sourceKid` names when the header names none) and, if valid, produces a replacement signature with `newKid`. Useful for algorithm migrations without touching payload bytes.  **A JWS signed by several keys** (a General JSON JWS with one signature per key, RFC 7515 §7.2.1 — what a PKCS#7 conversion emits for co-signed content). `sourceKid` is REQUIRED and names the ONE signer whose signature is replaced; `newKid` must be none of the kept signers (400 naming the member otherwise, before any key is gated). The caller holds `RESIGN` on `sourceKid` → `newKid` and `VERIFY` on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected `ank_kv`, and `newKid` on the RESIGN row, all before any signature is checked. Then **every** signature is verified under its own key before anything is signed: a single signature that does not verify refuses the whole request with 400 `invalid-input` and nothing is signed, so a re-signature never launders an invalid co-signature. The new signature takes the replaced position under a protected header built fresh for `newKid` (no member of the replaced header is copied); the payload is the token's, so that header declares `typ` `JWT` exactly when a received signature declares it (RFC 7519 §5.1: the payload is a claims set). A SIMPLE `newKid` signs a claims set only: over a token that declares none (a raw-octet payload) it is 400 before any signature is checked, and a composite `newKid` re-signs either. Every other signature — `protected`, `header` and `signature` — and the `payload` are returned exactly as received. `signatureResults` reports every verified input signature. The output is always the General JSON JWS (`serialization: COMPACT` is 400). When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its `sigTst` in its own entry's `header`, as a single-key re-sign carries it; every other signature keeps its `header`, and so its own timestamp, unchanged.  **Serialization selection.** The optional `serialization` field selects the representation of the RE-SIGNED output (the incoming form does not govern it) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped; the `output` column names the logical serialization tier. On the HTTP wire the re-signed JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope: a COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment compact form), a JAdES B-T result carries the RFC 3161 `sigTst` in the unprotected header. The re-sign metadata envelope (old/new key requested, per-leg material versions, algorithms, warnings) is ALWAYS present regardless of serialization. ",
                 "item": [
                            {
                                "name": "SIMPLE source (RSA-3072, PS256) re-signed by an ML-DSA-44 key",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"eyJkYXRhIjoiU0dWc2JHOGdRVzVyWVEiLCJpYXQiOjE3OTA2NTYyNDEsInRpZCI6IjdkM2E5YzFlLTRiMmYtNGU4YS05YzczLTI3NTAwMDAwMDAxMSJ9\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJ2ZXIiOiIyLjAiLCJhbmtfa3YiOjEsInR5cCI6IkpXVCIsImFsZyI6IlBTMjU2IiwidGlkIjoiN2QzYTljMWUtNGIyZi00ZThhLTljNzMtMjc1MDAwMDAwMDExIiwia2lkIjoibXktcnNhLTMwNzIta2V5In0\",\n      \"signature\" : \"wdF8GP8DwiIwD06LJCicETh1trDvid__nvPN4pAJV90cf6NI8P8ujrNx4uPRXzumcf1e6rSUuOnyL2KQWLO8DQP0_1x2sK8SaeY6td93tV44hKm3x55nAon6yunxFTHNWAC3p-Dn_xXCDzKFoWu0WtYwXVRhKITB-fJ-jZEtgl4emB4yGxIzlFFkzCs_nxGTydOG9Z6mvnf0sQLHyIAS9O2PltJhKhBYxb6S80Nm6nIWVXigOB71QCszqDkGgedWxayHzb7NgIhyOPzTCy2lXGHQYdd0mlh8PdZAcMTgpXaeTpKx__hL9WV4LVFZpBQcIccGqDThBu7w7ZDn3ioEhov7mPxvIkx028xKRP51HeEk4z-cbcXsWHJmpqet16CIH1-3PPJTDeA5FZcXUu4xlTrvhmURmldpuIKMvvFa3T_ftlbSOMsZVPwIGZrGvOU6hyVzVrZ5dd_-DpO_M1LjO6RixUEWmOYIFO0lakXJt6V3EHOP7zvE4Zvb_khHc1lN\"\n    } ]\n  },\n  \"newKid\" : \"my-mldsa-44-key\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/resign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "resign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies the incoming JWS (Compact or General JSON Serialization) under its embedded `oldKid` (or the key `sourceKid` names when the header names none) and, if valid, produces a replacement signature with `newKid`. Useful for algorithm migrations without touching payload bytes.  **A JWS signed by several keys** (a General JSON JWS with one signature per key, RFC 7515 §7.2.1 — what a PKCS#7 conversion emits for co-signed content). `sourceKid` is REQUIRED and names the ONE signer whose signature is replaced; `newKid` must be none of the kept signers (400 naming the member otherwise, before any key is gated). The caller holds `RESIGN` on `sourceKid` → `newKid` and `VERIFY` on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected `ank_kv`, and `newKid` on the RESIGN row, all before any signature is checked. Then **every** signature is verified under its own key before anything is signed: a single signature that does not verify refuses the whole request with 400 `invalid-input` and nothing is signed, so a re-signature never launders an invalid co-signature. The new signature takes the replaced position under a protected header built fresh for `newKid` (no member of the replaced header is copied); the payload is the token's, so that header declares `typ` `JWT` exactly when a received signature declares it (RFC 7519 §5.1: the payload is a claims set). A SIMPLE `newKid` signs a claims set only: over a token that declares none (a raw-octet payload) it is 400 before any signature is checked, and a composite `newKid` re-signs either. Every other signature — `protected`, `header` and `signature` — and the `payload` are returned exactly as received. `signatureResults` reports every verified input signature. The output is always the General JSON JWS (`serialization: COMPACT` is 400). When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its `sigTst` in its own entry's `header`, as a single-key re-sign carries it; every other signature keeps its `header`, and so its own timestamp, unchanged.  **Serialization selection.** The optional `serialization` field selects the representation of the RE-SIGNED output (the incoming form does not govern it) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped; the `output` column names the logical serialization tier. On the HTTP wire the re-signed JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope: a COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment compact form), a JAdES B-T result carries the RFC 3161 `sigTst` in the unprotected header. The re-sign metadata envelope (old/new key requested, per-leg material versions, algorithms, warnings) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Three signers: the treasurer's P-256 signature replaced by an ML-DSA-65 key",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"UXVhcnRlcmx5IGJvYXJkIHJlc29sdXRpb24gMjAyNi1RMw\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJhbGciOiJQUzI1NiIsImtpZCI6ImJvYXJkLWNoYWlyLXJzYSIsInZlciI6IjIuMCIsImFua19rdiI6MiwidGlkIjoiN2QzYTljMWUtNGIyZi00ZThhLTljNzMtMjc1MDAwMDAwMDExIiwiaWF0IjoxNzkwNjU2MjQwfQ\",\n      \"signature\" : \"Qm9hcmQgY2hhaXIgUlNBLVBTUyBzaWduYXR1cmUgb3ZlciB0aGUgcmVzb2x1dGlvbg\"\n    }, {\n      \"protected\" : \"eyJhbGciOiJFUzI1NiIsImtpZCI6InRyZWFzdXJlci1lYy1wMjU2IiwidmVyIjoiMi4wIiwiYW5rX2t2IjoxLCJ0aWQiOiI3ZDNhOWMxZS00YjJmLTRlOGEtOWM3My0yNzUwMDAwMDAwMTEiLCJpYXQiOjE3OTA2NTYyNDB9\",\n      \"signature\" : \"VHJlYXN1cmVyIEVDRFNBIFAtMjU2IHNpZ25hdHVyZSBvdmVyIHRoZSByZXNvbHV0aW9uIGJ5IHRoZSB0cmVhc3VyZXI\"\n    }, {\n      \"protected\" : \"eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJzZWNyZXRhcnktbWxkc2EiLCJ2ZXIiOiIyLjAiLCJhbmtfa3YiOjMsInRpZCI6IjdkM2E5YzFlLTRiMmYtNGU4YS05YzczLTI3NTAwMDAwMDAxMSIsImlhdCI6MTc5MDY1NjI0MH0\",\n      \"signature\" : \"U2VjcmV0YXJ5IE1MLURTQS02NSBzaWduYXR1cmUgb3ZlciB0aGUgcmVzb2x1dGlvbg\"\n    } ]\n  },\n  \"sourceKid\" : \"treasurer-ec-p256\",\n  \"newKid\" : \"treasurer-mldsa-65\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/resign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "resign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies the incoming JWS (Compact or General JSON Serialization) under its embedded `oldKid` (or the key `sourceKid` names when the header names none) and, if valid, produces a replacement signature with `newKid`. Useful for algorithm migrations without touching payload bytes.  **A JWS signed by several keys** (a General JSON JWS with one signature per key, RFC 7515 §7.2.1 — what a PKCS#7 conversion emits for co-signed content). `sourceKid` is REQUIRED and names the ONE signer whose signature is replaced; `newKid` must be none of the kept signers (400 naming the member otherwise, before any key is gated). The caller holds `RESIGN` on `sourceKid` → `newKid` and `VERIFY` on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected `ank_kv`, and `newKid` on the RESIGN row, all before any signature is checked. Then **every** signature is verified under its own key before anything is signed: a single signature that does not verify refuses the whole request with 400 `invalid-input` and nothing is signed, so a re-signature never launders an invalid co-signature. The new signature takes the replaced position under a protected header built fresh for `newKid` (no member of the replaced header is copied); the payload is the token's, so that header declares `typ` `JWT` exactly when a received signature declares it (RFC 7519 §5.1: the payload is a claims set). A SIMPLE `newKid` signs a claims set only: over a token that declares none (a raw-octet payload) it is 400 before any signature is checked, and a composite `newKid` re-signs either. Every other signature — `protected`, `header` and `signature` — and the `payload` are returned exactly as received. `signatureResults` reports every verified input signature. The output is always the General JSON JWS (`serialization: COMPACT` is 400). When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its `sigTst` in its own entry's `header`, as a single-key re-sign carries it; every other signature keeps its `header`, and so its own timestamp, unchanged.  **Serialization selection.** The optional `serialization` field selects the representation of the RE-SIGNED output (the incoming form does not govern it) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped; the `output` column names the logical serialization tier. On the HTTP wire the re-signed JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope: a COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment compact form), a JAdES B-T result carries the RFC 3161 `sigTst` in the unprotected header. The re-sign metadata envelope (old/new key requested, per-leg material versions, algorithms, warnings) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE source (Ed25519+ML-DSA-44) re-signed by a P-256+ML-DSA-44 key",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"SGVsbG8gQW5rYQ\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJhbGciOiJNTC1EU0EtNDQtRWQyNTUxOSIsImtpZCI6Imludm9pY2Utc2lnbmVyLTIwMjUiLCJhbmtfa3YiOjEsImlhdCI6MTc5MDY0NzEwNn0\",\n      \"signature\" : \"DA3fv0AHKs1Zy4Z6gsTnoVfZU6qkGjTcUPP7RS7arzhtY_tbughY7Fq6dvNWXKioGsCbhsQrHyNvYPwPk9ja4yDYyimGKgApHesalAjjQGa1tlQOD6G2P2vLfOp1t6UBCQGeNb5MbQ-zynRqjmD6mIQf9xYfbDoT9kuMFVhdiAiO7J0sBND_VCG4gOkxAv-pIpyX8eYHEf_W5_2J5I3c9t3x_ej4-5LGAri6k81AQ8uXrRwTJeOn-DqTwOBv8Z91jwP5dTXfNnGzNaUdOP6rjDhw3YaptSWsgFGyMuBoZ13VLfihT0H5u1DEkJfCRy4Er8mxMYuGUhFvyXpsNPB10mJ9CK96u_EsL8RI291EsfijJNGU6Rxqsb6cTtd6kyGfEzYJofubxaPGGUBiLwNbISkgIRiL8sR_EK9M-1DUCj5lvO84UCJo6vpC5FNhCinXFuOst6_DGQfQYJ5etvkc0MTiyGFU01a-9n1Hs8FR46ch1cExq5SoTUeu22O2-CM2v8JBpodxW6kpIyIdKOLIL7-K2-ORR0EXR8LY_CdwRmE_8lpaFgfSyUeS8_V-CiHLb2jGc2BGlE5GO5WfwiZUp6TcV-9xdTcy8ID7qbvcONTxTOcVwrfGO-NZVoweXDHm6y5Aj-fpZQbbJboMY8fdT5LScHvjT87UbEz0q3RCGPuuyVmpwYf8wZdhcp-KCEYHYX6l0WAcVh9e4PLP0khLwY1Hex-uGXHUx9J2Hrq0SqV8jGNrz2iAwrEo8BU0gK7yISyPUFQ1z47gSBFzV0kXyi5Z79nRriwpCuANg_pCR5IdTC2QR2VRyNeaG-VT_IBLDkpsFiqISbHf83KTO7tuc7b95Qt2KSI6zEaJi27_sAZC-RPAdKHUogNqYsI9Px0f1l7o_r8w2TmZZPa8txEpg_BJQlIjCuh9jTmaiXoG835lb20VWs3qRWl3dKUI8CgMwa9c7pvrzR2hJHoxNF-RxVuKDt35ACSnJXLLjdcR4Ykp2sjKM3kuNntskTCS_FUDmMUQNa_Jqnt2484FphoTkF3xfgAIyPWi4Qzy99XlbaJ6IwCOwrrnpPd7HM3J6H5j3VhX0Fy5cCxgiDnCxtbx7qk0MY2ucy6oo2ojHI63_vkkSTZ-IvW3VdAEf1RcHPl5sxIBnzTsD3zRcPIASRytKKF_lGE1TVEk-3xepjNNnKzy7ivcf5hznV5YNuNVHL749tHgF50t0sZjj2JBTDQrt-KMZF3hSNyaljjmPJQXSInl35A-Fdy0ZbWTupl-OP1A4-PUR-6S1ztmYtmwocghkGPzz8qyfJHecG_4k1pSXJKeOIw501dkvk39ga5Fpza1fn_X-0CWSDUuJ-drVah-RvhhakilqUbFGUdB41kYmPMqRAllM4CY5wKLwqynSGf9Pa-UGPsPfZCZf8FR5hlKPbYOe8f_hY2Sm167g5nrq3xB4EX8fIR4xgTfS35CAZkRzYr264o7leR_i6TYv3VcFV0L2ySUOJ03N6gfdSgTkH-X9CgsQbVVxsXMbDT4f4jyuBT9DFwYYyGB6oym5287bVsV3JMJfqThABy4xw9-G9CAj4_93duRBTFxsofPN5XwlXtb4jlIWhCsV-_rK20ja5QE_Sy9etNSJaemWmokYV09pxOHP_phvkJO9NotnsFWxMkusQdYEgvp6Xg6ajAReMIardVkk_Lf_WGNy8kTtgfn2nbkxeeVciLXwDuq5SiEDAvXKrBEqQd5tcM5F9c9Br-7D_4HIk9k8MQgJFNA6eytDMstj4Z4GMXmHwkDy-IT_IdQc6WowIWZ7ADP-msRK3A7eapuHZ_WKgbDpYe_DDxkVxaXd6DHPBD74EmUS1kvrkOt-IxTcl1OOAN1DqjIsU-O33u4XARXuY20nvflfJhbD4PRgZMC_154riOWRN99I5MTsOgHNOZCmEwsEPhyQnQTC_ZQPF9xxcrKiwExGwStTV-HAX_M4HhIElpIhgkr0IgOH1I9GMC5yP1gtlIxCA82c1DQvT1l_tHA-nwmsJIXcGE3HyNNcdK8qKepyVTbzwuQtfAGVNWH8fEO494zsD8sRUtNSTIsX3snqNBzqliB8mXtPdA0SxLV0lkqkHQ1G5wGDfgGhkzIwkUnxShQn2uSKHpkC220z_p4RHcn2frkvWU8TgfXY0klhx0U1aAZ6yHYhW2NsHYFHiIGqMpScHkJ92_mPLc4OF-NaddHZJLNMNzN5BTB2wu_W_Yq5jmdb64IpNaN9-Md7_edU3htUGwHiuqcqIc5FMjzxZM3ehxPp0kqTLuNMcONhm4YHPWud1dN-ZmvCIVANNhmZC_tr4Pa5pS62BO1LuYn04eZ9MBggnS_j-CnqcN9vkh9oN-XadmNPY-MRHHEDp-e6Qx-Of4AjFNH8AzugG1ELcGM6n0_H3Xbq3b9eKELSPpdgP37FmHQCSLedsjDNeDWTd9-Mw0CrvXIH3008asmUGSD8abNZxLQQvcYk1LqVDvmzb6BUQDWNJY8zMGdetmKjL2T3rPoT00FC1cgDRxw4k2fX3q2FwkABlqiXmjK_Sw88kLV5YfZqSIPAEWLVfZC3fZjdb1QJDukpYM3K5bfLQyiAI2Y9fWBuMaTMzALYmTvGvlJztX5WzWKar_XGy4ZLYVjLY_MGarxuJChJiMBPmsFYmRbaw9XLjvxZVeoscU05JbVoDkQz7w31EYm7ZTtT1jmkf7DlLrvItMGNAr0TRuWtG4k2j7Q4JgzEAEea8SU7me9law2Uv0g5BdZdqJCLKsBxSUsw3A0w1XN2EdxE63CHu4Nj8bwaHVl1HO_1Y3ZxBzym7MQPb_o8Ep8XjTrPqhgwL3djIWACKTJsWU6am51QXNvxOGuUhjiYFX0FsrGZJeyOn6Yf4kpvIPMfP9uZ0lgMIFBAPSfeMy5PQXIIYERoXMG0CgIDzazVUr7Y5qfa1plxJLpxJQ9XsFcVyuTmKgkNs2mjhTnUguQ1N59Q4989WCaFNH0aJDBapfFoEuhvYIMLnppfIsLbJ58VO9vALiAjKoWQ3R_LS8cHuMuClCqkdlQ7yf6YC-qGqCLNDMqOAahLhblhjuVwC3J-pO_jahRo8Di3JSXvHrfCRrSDh7M40sQEilNW3uRoKSztLjJ0974BBghYWJjaHWEqLC0ur_L2-H2Ahc1OlteZnyCoLzIz9_l8fwFCUJZYmZndXqRkrnF2OPr-wAAAAAAAAAAAAAAABAiM0R2EnVgC05OvIWLpr22s7bSnheK2FoOmcWmTNt6wxb79PyRYeMFUzle-mUPh5-aF00dlow8WZXR7KsD9zYI6D8F\"\n    } ]\n  },\n  \"newKid\" : \"invoice-signer-2026\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/resign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "resign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies the incoming JWS (Compact or General JSON Serialization) under its embedded `oldKid` (or the key `sourceKid` names when the header names none) and, if valid, produces a replacement signature with `newKid`. Useful for algorithm migrations without touching payload bytes.  **A JWS signed by several keys** (a General JSON JWS with one signature per key, RFC 7515 §7.2.1 — what a PKCS#7 conversion emits for co-signed content). `sourceKid` is REQUIRED and names the ONE signer whose signature is replaced; `newKid` must be none of the kept signers (400 naming the member otherwise, before any key is gated). The caller holds `RESIGN` on `sourceKid` → `newKid` and `VERIFY` on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected `ank_kv`, and `newKid` on the RESIGN row, all before any signature is checked. Then **every** signature is verified under its own key before anything is signed: a single signature that does not verify refuses the whole request with 400 `invalid-input` and nothing is signed, so a re-signature never launders an invalid co-signature. The new signature takes the replaced position under a protected header built fresh for `newKid` (no member of the replaced header is copied); the payload is the token's, so that header declares `typ` `JWT` exactly when a received signature declares it (RFC 7519 §5.1: the payload is a claims set). A SIMPLE `newKid` signs a claims set only: over a token that declares none (a raw-octet payload) it is 400 before any signature is checked, and a composite `newKid` re-signs either. Every other signature — `protected`, `header` and `signature` — and the `payload` are returned exactly as received. `signatureResults` reports every verified input signature. The output is always the General JSON JWS (`serialization: COMPACT` is 400). When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its `sigTst` in its own entry's `header`, as a single-key re-sign carries it; every other signature keeps its `header`, and so its own timestamp, unchanged.  **Serialization selection.** The optional `serialization` field selects the representation of the RE-SIGNED output (the incoming form does not govern it) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped; the `output` column names the logical serialization tier. On the HTTP wire the re-signed JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope: a COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment compact form), a JAdES B-T result carries the RFC 3161 `sigTst` in the unprotected header. The re-sign metadata envelope (old/new key requested, per-leg material versions, algorithms, warnings) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Header names no key: sourceKid supplies it",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"eyJkYXRhIjoiU0dWc2JHOGdRVzVyWVEiLCJpYXQiOjE3OTA2NTYyNDEsInRpZCI6IjdkM2E5YzFlLTRiMmYtNGU4YS05YzczLTI3NTAwMDAwMDAxMSJ9\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJ0eXAiOiJKT1NFIiwiYWxnIjoiUFMyNTYifQ\",\n      \"signature\" : \"UtlqZxpbEF2NBltNjFvCDAxHSgZNO7M759FXw_ZKBQKPqokTDBsaz1Bxpb0CsHFK-vgHUeZbqoIxWrqyFYTzwsZFQiqH2ZDO3IeYRCfdPJ5yBUfQ03h9Bd-tRDfqC9f38wNGrsp1DpJPOieDOtXx9Oa958w2x0NcxRRKaET5b4uNw1AGQXGxaqyIeuvXjWYJYh3vY4IcoOJWRYmIFHH_jz1jS45JNvKLXgHyOcjouc8Gs5PNz4e4MtDtfMjcQXv83f-xeTk_7zsIFnX4F9teoZfxRYlxAfcCsGfFMke9hWjmq0U5pWZYvQI2q6l1TBiU5kJdOiP2_URppjmiULF7Ts7rCkJi_JawIICKcU-nGyN-mQque36m42gYl4alVnMUgrj_icEmlQFF4nEb6iVFEnKQKvIKMq0lG0kYyvfJ5rBG3kzM5YNCLGhWB0JvPwLEzk_qG-r-pDmtB7b1X7Fa0fF548ybjNOG7uzhEPxUQ2Gzl3QHFbx3DE_jsVjM8ZLD\"\n    } ]\n  },\n  \"newKid\" : \"my-mldsa-44-key\",\n  \"sourceKid\" : \"legacy-sign-key-v1\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/resign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "resign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies the incoming JWS (Compact or General JSON Serialization) under its embedded `oldKid` (or the key `sourceKid` names when the header names none) and, if valid, produces a replacement signature with `newKid`. Useful for algorithm migrations without touching payload bytes.  **A JWS signed by several keys** (a General JSON JWS with one signature per key, RFC 7515 §7.2.1 — what a PKCS#7 conversion emits for co-signed content). `sourceKid` is REQUIRED and names the ONE signer whose signature is replaced; `newKid` must be none of the kept signers (400 naming the member otherwise, before any key is gated). The caller holds `RESIGN` on `sourceKid` → `newKid` and `VERIFY` on every kept signer; every signer is judged on the VERIFY lifecycle row at its protected `ank_kv`, and `newKid` on the RESIGN row, all before any signature is checked. Then **every** signature is verified under its own key before anything is signed: a single signature that does not verify refuses the whole request with 400 `invalid-input` and nothing is signed, so a re-signature never launders an invalid co-signature. The new signature takes the replaced position under a protected header built fresh for `newKid` (no member of the replaced header is copied); the payload is the token's, so that header declares `typ` `JWT` exactly when a received signature declares it (RFC 7519 §5.1: the payload is a claims set). A SIMPLE `newKid` signs a claims set only: over a token that declares none (a raw-octet payload) it is 400 before any signature is checked, and a composite `newKid` re-signs either. Every other signature — `protected`, `header` and `signature` — and the `payload` are returned exactly as received. `signatureResults` reports every verified input signature. The output is always the General JSON JWS (`serialization: COMPACT` is 400). When the deployment requires an RFC 3161 timestamp on every new signature, the new signature carries its `sigTst` in its own entry's `header`, as a single-key re-sign carries it; every other signature keeps its `header`, and so its own timestamp, unchanged.  **Serialization selection.** The optional `serialization` field selects the representation of the RE-SIGNED output (the incoming form does not govern it) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped; the `output` column names the logical serialization tier. On the HTTP wire the re-signed JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope: a COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment compact form), a JAdES B-T result carries the RFC 3161 `sigTst` in the unprotected header. The re-sign metadata envelope (old/new key requested, per-leg material versions, algorithms, warnings) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/sign",
                "description": "Signs Base64-encoded `data` with the private key associated with `kid` and returns the produced JWS inside a signing-metadata envelope. Supported algorithms: ML-DSA, Falcon, RSA-PSS (PS256), ECDSA (ES256/384/512 on the P-curves, ESB256/384/512 on the brainpool curves), and COMPOSITE hybrid keys.  **Serialization selection.** The optional `serialization` field expresses the client's chosen JWS representation and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers exist: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the JWS Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped — the compact+REQUIRED row is the only rejection. The `output` column names the logical serialization tier; see \"Output to parse\" for the exact wire shape.  **Output to parse.** On the HTTP wire the produced JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope. A COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment RFC 7515 §7.1 compact form, as the SDK renders it); a JAdES B-T result carries the RFC 3161 `sigTst` in the top-level unprotected `header` (`header.etsiU[].sigTst`, a member outside the RFC 7515 §7.2.1 General syntax). A COMPOSITE key's result is one signature too: one value, under one protected header `{alg, kid, ank_kv, iat[, exp]}` in that order. `iat` is stated whenever this deployment's JWS local clock issues it (`ankasecure.jws.local-clock.enabled` and `include-iat`, both on by default), and `exp` = `iat` + `validityDays` × 86400 when `validityDays` is sent. `iat` and `exp` in a JWS protected header are this platform's convention, not JWS Header Parameters registered with IANA, and neither is listed in `crit`: an external JOSE verifier that does not know them ignores them (RFC 7515 §4, §4.1.11), so it neither enforces the expiry nor refuses the signature for it. This platform's verifiers judge both while claim-time validation is on (`ankasecure.jws.local-clock.validation.enabled`, on by default), within `clock-skew-seconds`: an `iat` in the future is refused, and an `exp` in the past is refused while `validation.reject-expired` is on (the default). The surrounding metadata envelope (`keyRequested`, `materialVersion`, `algorithmUsed`, `warnings`) is ALWAYS present regardless of serialization. ",
                 "item": [
                            {
                                "name": "Sign request",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"kid\" : \"mySigningKeyKid\",\n  \"data\" : \"SGVsbG8gQW5rYQ==\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/sign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "sign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Signs Base64-encoded `data` with the private key associated with `kid` and returns the produced JWS inside a signing-metadata envelope. Supported algorithms: ML-DSA, Falcon, RSA-PSS (PS256), ECDSA (ES256/384/512 on the P-curves, ESB256/384/512 on the brainpool curves), and COMPOSITE hybrid keys.  **Serialization selection.** The optional `serialization` field expresses the client's chosen JWS representation and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers exist: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the JWS Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped — the compact+REQUIRED row is the only rejection. The `output` column names the logical serialization tier; see \"Output to parse\" for the exact wire shape.  **Output to parse.** On the HTTP wire the produced JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope. A COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment RFC 7515 §7.1 compact form, as the SDK renders it); a JAdES B-T result carries the RFC 3161 `sigTst` in the top-level unprotected `header` (`header.etsiU[].sigTst`, a member outside the RFC 7515 §7.2.1 General syntax). A COMPOSITE key's result is one signature too: one value, under one protected header `{alg, kid, ank_kv, iat[, exp]}` in that order. `iat` is stated whenever this deployment's JWS local clock issues it (`ankasecure.jws.local-clock.enabled` and `include-iat`, both on by default), and `exp` = `iat` + `validityDays` × 86400 when `validityDays` is sent. `iat` and `exp` in a JWS protected header are this platform's convention, not JWS Header Parameters registered with IANA, and neither is listed in `crit`: an external JOSE verifier that does not know them ignores them (RFC 7515 §4, §4.1.11), so it neither enforces the expiry nor refuses the signature for it. This platform's verifiers judge both while claim-time validation is on (`ankasecure.jws.local-clock.validation.enabled`, on by default), within `clock-skew-seconds`: an `iat` in the future is refused, and an `exp` in the past is refused while `validation.reject-expired` is on (the default). The surrounding metadata envelope (`keyRequested`, `materialVersion`, `algorithmUsed`, `warnings`) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE key, signature valid for 365 days",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"kid\" : \"invoice-signer-2025\",\n  \"data\" : \"SGVsbG8gQW5rYQ==\",\n  \"validityDays\" : 365\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/sign",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "sign"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Signs Base64-encoded `data` with the private key associated with `kid` and returns the produced JWS inside a signing-metadata envelope. Supported algorithms: ML-DSA, Falcon, RSA-PSS (PS256), ECDSA (ES256/384/512 on the P-curves, ESB256/384/512 on the brainpool curves), and COMPOSITE hybrid keys.  **Serialization selection.** The optional `serialization` field expresses the client's chosen JWS representation and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers exist: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the JWS Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` token structurally cannot carry it).  **Behavior truth table** (`serialization` × effective stamping → output form):  | `serialization` | stamping | output | 400? | |---|---|---|---| | omitted | OFF | compact JWS | no | | omitted | REQUIRED | JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T) | no | | `COMPACT` | OFF | compact JWS | no | | `COMPACT` | REQUIRED | — | **400** `serialization-incompatible-with-timestamp` | | `JSON` | OFF | JWS-JSON, no `sigTst` | no | | `JSON` | REQUIRED | JWS-JSON + `sigTst` (JAdES B-T) | no |  An explicit `COMPACT` is never silently upgraded and a mandated stamp is never dropped — the compact+REQUIRED row is the only rejection. The `output` column names the logical serialization tier; see \"Output to parse\" for the exact wire shape.  **Output to parse.** On the HTTP wire the produced JWS is ALWAYS carried in the typed `jwsToken` (RFC 7515 §7.2 JWS JSON Serialization) envelope. A COMPACT / unstamped result is a single-signature object with no `sigTst` (losslessly convertible to the 3-segment RFC 7515 §7.1 compact form, as the SDK renders it); a JAdES B-T result carries the RFC 3161 `sigTst` in the top-level unprotected `header` (`header.etsiU[].sigTst`, a member outside the RFC 7515 §7.2.1 General syntax). A COMPOSITE key's result is one signature too: one value, under one protected header `{alg, kid, ank_kv, iat[, exp]}` in that order. `iat` is stated whenever this deployment's JWS local clock issues it (`ankasecure.jws.local-clock.enabled` and `include-iat`, both on by default), and `exp` = `iat` + `validityDays` × 86400 when `validityDays` is sent. `iat` and `exp` in a JWS protected header are this platform's convention, not JWS Header Parameters registered with IANA, and neither is listed in `crit`: an external JOSE verifier that does not know them ignores them (RFC 7515 §4, §4.1.11), so it neither enforces the expiry nor refuses the signature for it. This platform's verifiers judge both while claim-time validation is on (`ankasecure.jws.local-clock.validation.enabled`, on by default), within `clock-skew-seconds`: an `iat` in the future is refused, and an `exp` in the past is refused while `validation.reject-expired` is on (the default). The surrounding metadata envelope (`keyRequested`, `materialVersion`, `algorithmUsed`, `warnings`) is ALWAYS present regardless of serialization. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/sign-encrypt",
                "description": "Performs sign-then-encrypt operation: signs data with signKid, then encrypts the resulting JWS with encryptKid to produce a nested JWE(JWS) structure.  The two keys must be different.  **Serialization selection.** The optional `serialization` field selects the representation of the INNER signed JWS (before it is encrypted into the outer JWE) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers apply to the inner JWS: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` inner token structurally cannot carry it). Truth table (`serialization` × effective stamping → inner form): omitted+OFF → compact; omitted+REQUIRED → JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T); `COMPACT`+OFF → compact; `COMPACT`+REQUIRED → **400** `serialization-incompatible-with-timestamp` (rejected BEFORE any signing or encryption); `JSON`+OFF → JWS-JSON, no `sigTst`; `JSON`+REQUIRED → JWS-JSON + `sigTst`. It never adds or drops a timestamp and does not change the outer JWE. The `jweToken` field and the separated sign/encrypt metadata envelope are ALWAYS present regardless of serialization.  Uses JWE General JSON Serialization (RFC 7516 §7.2) and JWS General JSON Serialization (RFC 7515 §7.2) uniformly across SIMPLE and COMPOSITE keys. COMPOSITE keys enable hybrid post-quantum cryptography with a composite signature (COMPOSITE_SIGNATURE) and combined key encapsulation (COMPOSITE_KEM_COMBINE).  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, exactly as on the streaming `/api/v3/crypto/stream/sign-encrypt`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `signKid` with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `encryptKid` — for example HMAC-SHA256 + ML-KEM-768, ML-DSA-65 + AES-GCM-256, or COMPOSITE_SIGNATURE + COMPOSITE_KEM_COMBINE. A key of the wrong kind for its leg (an encryption key as `signKid`, a signature key as `encryptKid`) is refused **400** `invalid-input` before anything is signed.  A COMPOSITE `signKid` signs with one composite signature under the protected header `{alg, kid, ank_kv, iat[, exp]}`; `validityDays` sets its `exp` exactly as for a SIMPLE key.  The JWE outer header includes cty=\"JWS\" to indicate nested content. ",
                 "item": [
                            {
                                "name": "SIMPLE keys (asymmetric PQC)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"data\" : \"SGVsbG8gQW5rYQ==\",\n  \"signKid\" : \"myMLDSASignKey\",\n  \"encryptKid\" : \"myMLKEMEncKey\",\n  \"validityDays\" : 365\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/sign-encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "sign-encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Performs sign-then-encrypt operation: signs data with signKid, then encrypts the resulting JWS with encryptKid to produce a nested JWE(JWS) structure.  The two keys must be different.  **Serialization selection.** The optional `serialization` field selects the representation of the INNER signed JWS (before it is encrypted into the outer JWE) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers apply to the inner JWS: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` inner token structurally cannot carry it). Truth table (`serialization` × effective stamping → inner form): omitted+OFF → compact; omitted+REQUIRED → JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T); `COMPACT`+OFF → compact; `COMPACT`+REQUIRED → **400** `serialization-incompatible-with-timestamp` (rejected BEFORE any signing or encryption); `JSON`+OFF → JWS-JSON, no `sigTst`; `JSON`+REQUIRED → JWS-JSON + `sigTst`. It never adds or drops a timestamp and does not change the outer JWE. The `jweToken` field and the separated sign/encrypt metadata envelope are ALWAYS present regardless of serialization.  Uses JWE General JSON Serialization (RFC 7516 §7.2) and JWS General JSON Serialization (RFC 7515 §7.2) uniformly across SIMPLE and COMPOSITE keys. COMPOSITE keys enable hybrid post-quantum cryptography with a composite signature (COMPOSITE_SIGNATURE) and combined key encapsulation (COMPOSITE_KEM_COMBINE).  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, exactly as on the streaming `/api/v3/crypto/stream/sign-encrypt`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `signKid` with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `encryptKid` — for example HMAC-SHA256 + ML-KEM-768, ML-DSA-65 + AES-GCM-256, or COMPOSITE_SIGNATURE + COMPOSITE_KEM_COMBINE. A key of the wrong kind for its leg (an encryption key as `signKid`, a signature key as `encryptKid`) is refused **400** `invalid-input` before anything is signed.  A COMPOSITE `signKid` signs with one composite signature under the protected header `{alg, kid, ank_kv, iat[, exp]}`; `validityDays` sets its `exp` exactly as for a SIMPLE key.  The JWE outer header includes cty=\"JWS\" to indicate nested content. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE keys (hybrid PQC)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"data\" : \"SGVsbG8gQW5rYQ==\",\n  \"signKid\" : \"invoice-signer-2025\",\n  \"encryptKid\" : \"myCompositeHybridKEMKey\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/sign-encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "sign-encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Performs sign-then-encrypt operation: signs data with signKid, then encrypts the resulting JWS with encryptKid to produce a nested JWE(JWS) structure.  The two keys must be different.  **Serialization selection.** The optional `serialization` field selects the representation of the INNER signed JWS (before it is encrypted into the outer JWE) and is orthogonal to the backend-authoritative RFC 3161 time-stamping policy. Two honest compliance tiers apply to the inner JWS: **RFC 7515 JWS** (`COMPACT` = §7.1 three-segment compact, or `JSON` = §7.2 JWS JSON Serialization) and **JAdES B-T** (JWS JSON Serialization only, carrying an RFC 3161 qualified timestamp `sigTst` in the Unprotected Header per ETSI TS 119 182-1 — a `COMPACT` inner token structurally cannot carry it). Truth table (`serialization` × effective stamping → inner form): omitted+OFF → compact; omitted+REQUIRED → JWS-JSON + `sigTst` (auto-upgrade, JAdES B-T); `COMPACT`+OFF → compact; `COMPACT`+REQUIRED → **400** `serialization-incompatible-with-timestamp` (rejected BEFORE any signing or encryption); `JSON`+OFF → JWS-JSON, no `sigTst`; `JSON`+REQUIRED → JWS-JSON + `sigTst`. It never adds or drops a timestamp and does not change the outer JWE. The `jweToken` field and the separated sign/encrypt metadata envelope are ALWAYS present regardless of serialization.  Uses JWE General JSON Serialization (RFC 7516 §7.2) and JWS General JSON Serialization (RFC 7515 §7.2) uniformly across SIMPLE and COMPOSITE keys. COMPOSITE keys enable hybrid post-quantum cryptography with a composite signature (COMPOSITE_SIGNATURE) and combined key encapsulation (COMPOSITE_KEM_COMBINE).  **Key pairs this buffered route serves: every one.** Each leg runs with the service of its own key, exactly as on the streaming `/api/v3/crypto/stream/sign-encrypt`: a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `signKid` with a SIMPLE symmetric, SIMPLE asymmetric or COMPOSITE `encryptKid` — for example HMAC-SHA256 + ML-KEM-768, ML-DSA-65 + AES-GCM-256, or COMPOSITE_SIGNATURE + COMPOSITE_KEM_COMBINE. A key of the wrong kind for its leg (an encryption key as `signKid`, a signature key as `encryptKid`) is refused **400** `invalid-input` before anything is signed.  A COMPOSITE `signKid` signs with one composite signature under the protected header `{alg, kid, ank_kv, iat[, exp]}`; `validityDays` sets its `exp` exactly as for a SIMPLE key.  The JWE outer header includes cty=\"JWS\" to indicate nested content. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/crypto/verify",
                "description": "Verifies a JWS and reports the cryptographic verdict plus key metadata. Serialization is AUTO-DETECTED — both RFC 7515 §7.1 Compact (three dot-separated segments) and §7.2 JWS JSON Serialization inputs are accepted with no `serialization` parameter. Every key signs with ONE signature: a COMPOSITE signature is one value over the RFC 7515 signing input (the ML-DSA and classical component signatures concatenated), named by `kid`, `ank_kv` and the composite `alg` in its protected header; it is valid only when both components verify.  **A JWS signed by several keys.** A General JWS (RFC 7515 §7.2.1) may carry one signature per key, each naming its key in its own protected header; a composite key is one of them, with its one value. The token is first classified from its headers alone, before any key is looked up: a root member besides `payload` and `signatures`, a key named by two signatures, an HMAC `alg`, or more signatures than the deployment admits in one token is refused with 422, and signatures declaring different `b64` values with 400. Then every signer is gated in token order — every Capability Grant decision for `VERIFY` (a grant covering several signers is charged once), then every key-lifecycle decision on the `VERIFY` row at the version its `ank_kv` names (PRIMARY when it names none) — and the first refusal is a 403 that names no key and carries no verdict. Only then is each signature verified under its own key. `valid` is `true` only when EVERY signature verifies: a token with any failing signature is invalid, never a partial success.  **Response.** `signatureResults` carries one entry per signature, in token order — its `kid`, the key's catalogue `algorithm`, the `materialVersion` its key resolved to, and its own `verified` verdict. A JWS signed by one key answers one entry. No member names \"the\" key of the token.  **Qualified timestamp (JAdES B-T, informational).** When the verified JWS carries an embedded RFC 3161 qualified timestamp (JAdES `sigTst`), the response surfaces an informational `qualifiedTimestamp` block — `present`, `trustStatus` (VALID/SIGNATURE_INVALID/IMPRINT_MISMATCH/UNTRUSTED/REVOKED/EXPIRED), `genTime`, `serialNumber`, `policyOid`. The token is judged by checks in a fixed order and the first that fails decides `trustStatus`: the token parses and carries its signer's certificate (else `UNTRUSTED`); its own signature and certificate identifiers verify (else `SIGNATURE_INVALID`); its RFC 3161 message imprint declares SHA-256, SHA-384 or SHA-512 with absent or NULL parameters and a digest of that length (else `UNTRUSTED`); the imprint is the digest, under the token's own algorithm, of the ASCII signature value presented in this JWS (else `IMPRINT_MISMATCH` — the token time-stamps other bytes); only then is the TSA certificate judged, again first failure deciding: the signer's extended key usage (else `UNTRUSTED`), the signer's validity at `genTime` (else `EXPIRED`), a configured trust anchor (else `UNTRUSTED`), the path at `genTime` (else `EXPIRED` or `UNTRUSTED`; a signer that is itself a configured self-signed anchor passes here and skips the next check), and, only when the deployment checks revocation (the default), its revocation by RFC 3161 section 4 (else `REVOKED`, or `UNTRUSTED` when undetermined under the deployment's hard-fail revocation posture, the default); `VALID` when all pass, and `UNTRUSTED` when a certificate check cannot be completed at all. The token's age is not judged: its `genTime` was compared with the clock when the time-stamping authority's reply was received at signing, so a stamp verifies `VALID` however long ago it was issued. The three token fields are reported only for a verdict of the TSA-certificate checks, and are absent for every earlier one. Verification makes no call to the time-stamping authority and does not depend on the tenant's time-stamping settings. This block is purely informational and NEVER flips the boolean `valid`: a cryptographically valid signature with an absent, untrusted, or revoked timestamp still returns `valid = true`. The block is omitted for a compact or an unstamped JWS. ",
                 "item": [
                            {
                                "name": "SIMPLE key (RSA-3072, PS256)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"eyJkYXRhIjoiU0dWc2JHOGdRVzVyWVEiLCJpYXQiOjE3OTA2NTYyNDEsInRpZCI6IjdkM2E5YzFlLTRiMmYtNGU4YS05YzczLTI3NTAwMDAwMDAxMSJ9\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJ2ZXIiOiIyLjAiLCJhbmtfa3YiOjEsInR5cCI6IkpXVCIsImFsZyI6IlBTMjU2IiwidGlkIjoiN2QzYTljMWUtNGIyZi00ZThhLTljNzMtMjc1MDAwMDAwMDExIiwia2lkIjoibXktcnNhLTMwNzIta2V5In0\",\n      \"signature\" : \"wdF8GP8DwiIwD06LJCicETh1trDvid__nvPN4pAJV90cf6NI8P8ujrNx4uPRXzumcf1e6rSUuOnyL2KQWLO8DQP0_1x2sK8SaeY6td93tV44hKm3x55nAon6yunxFTHNWAC3p-Dn_xXCDzKFoWu0WtYwXVRhKITB-fJ-jZEtgl4emB4yGxIzlFFkzCs_nxGTydOG9Z6mvnf0sQLHyIAS9O2PltJhKhBYxb6S80Nm6nIWVXigOB71QCszqDkGgedWxayHzb7NgIhyOPzTCy2lXGHQYdd0mlh8PdZAcMTgpXaeTpKx__hL9WV4LVFZpBQcIccGqDThBu7w7ZDn3ioEhov7mPxvIkx028xKRP51HeEk4z-cbcXsWHJmpqet16CIH1-3PPJTDeA5FZcXUu4xlTrvhmURmldpuIKMvvFa3T_ftlbSOMsZVPwIGZrGvOU6hyVzVrZ5dd_-DpO_M1LjO6RixUEWmOYIFO0lakXJt6V3EHOP7zvE4Zvb_khHc1lN\"\n    } ]\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies a JWS and reports the cryptographic verdict plus key metadata. Serialization is AUTO-DETECTED — both RFC 7515 §7.1 Compact (three dot-separated segments) and §7.2 JWS JSON Serialization inputs are accepted with no `serialization` parameter. Every key signs with ONE signature: a COMPOSITE signature is one value over the RFC 7515 signing input (the ML-DSA and classical component signatures concatenated), named by `kid`, `ank_kv` and the composite `alg` in its protected header; it is valid only when both components verify.  **A JWS signed by several keys.** A General JWS (RFC 7515 §7.2.1) may carry one signature per key, each naming its key in its own protected header; a composite key is one of them, with its one value. The token is first classified from its headers alone, before any key is looked up: a root member besides `payload` and `signatures`, a key named by two signatures, an HMAC `alg`, or more signatures than the deployment admits in one token is refused with 422, and signatures declaring different `b64` values with 400. Then every signer is gated in token order — every Capability Grant decision for `VERIFY` (a grant covering several signers is charged once), then every key-lifecycle decision on the `VERIFY` row at the version its `ank_kv` names (PRIMARY when it names none) — and the first refusal is a 403 that names no key and carries no verdict. Only then is each signature verified under its own key. `valid` is `true` only when EVERY signature verifies: a token with any failing signature is invalid, never a partial success.  **Response.** `signatureResults` carries one entry per signature, in token order — its `kid`, the key's catalogue `algorithm`, the `materialVersion` its key resolved to, and its own `verified` verdict. A JWS signed by one key answers one entry. No member names \"the\" key of the token.  **Qualified timestamp (JAdES B-T, informational).** When the verified JWS carries an embedded RFC 3161 qualified timestamp (JAdES `sigTst`), the response surfaces an informational `qualifiedTimestamp` block — `present`, `trustStatus` (VALID/SIGNATURE_INVALID/IMPRINT_MISMATCH/UNTRUSTED/REVOKED/EXPIRED), `genTime`, `serialNumber`, `policyOid`. The token is judged by checks in a fixed order and the first that fails decides `trustStatus`: the token parses and carries its signer's certificate (else `UNTRUSTED`); its own signature and certificate identifiers verify (else `SIGNATURE_INVALID`); its RFC 3161 message imprint declares SHA-256, SHA-384 or SHA-512 with absent or NULL parameters and a digest of that length (else `UNTRUSTED`); the imprint is the digest, under the token's own algorithm, of the ASCII signature value presented in this JWS (else `IMPRINT_MISMATCH` — the token time-stamps other bytes); only then is the TSA certificate judged, again first failure deciding: the signer's extended key usage (else `UNTRUSTED`), the signer's validity at `genTime` (else `EXPIRED`), a configured trust anchor (else `UNTRUSTED`), the path at `genTime` (else `EXPIRED` or `UNTRUSTED`; a signer that is itself a configured self-signed anchor passes here and skips the next check), and, only when the deployment checks revocation (the default), its revocation by RFC 3161 section 4 (else `REVOKED`, or `UNTRUSTED` when undetermined under the deployment's hard-fail revocation posture, the default); `VALID` when all pass, and `UNTRUSTED` when a certificate check cannot be completed at all. The token's age is not judged: its `genTime` was compared with the clock when the time-stamping authority's reply was received at signing, so a stamp verifies `VALID` however long ago it was issued. The three token fields are reported only for a verdict of the TSA-certificate checks, and are absent for every earlier one. Verification makes no call to the time-stamping authority and does not depend on the tenant's time-stamping settings. This block is purely informational and NEVER flips the boolean `valid`: a cryptographically valid signature with an absent, untrusted, or revoked timestamp still returns `valid = true`. The block is omitted for a compact or an unstamped JWS. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "Three signers (General JSON, one signature per key)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"UXVhcnRlcmx5IGJvYXJkIHJlc29sdXRpb24gMjAyNi1RMw\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJhbGciOiJQUzI1NiIsImtpZCI6ImJvYXJkLWNoYWlyLXJzYSIsInZlciI6IjIuMCIsImFua19rdiI6MiwidGlkIjoiN2QzYTljMWUtNGIyZi00ZThhLTljNzMtMjc1MDAwMDAwMDExIiwiaWF0IjoxNzkwNjU2MjQwfQ\",\n      \"signature\" : \"Qm9hcmQgY2hhaXIgUlNBLVBTUyBzaWduYXR1cmUgb3ZlciB0aGUgcmVzb2x1dGlvbg\"\n    }, {\n      \"protected\" : \"eyJhbGciOiJFUzI1NiIsImtpZCI6InRyZWFzdXJlci1lYy1wMjU2IiwidmVyIjoiMi4wIiwiYW5rX2t2IjoxLCJ0aWQiOiI3ZDNhOWMxZS00YjJmLTRlOGEtOWM3My0yNzUwMDAwMDAwMTEiLCJpYXQiOjE3OTA2NTYyNDB9\",\n      \"signature\" : \"VHJlYXN1cmVyIEVDRFNBIFAtMjU2IHNpZ25hdHVyZSBvdmVyIHRoZSByZXNvbHV0aW9uIGJ5IHRoZSB0cmVhc3VyZXI\"\n    }, {\n      \"protected\" : \"eyJhbGciOiJNTC1EU0EtNjUiLCJraWQiOiJzZWNyZXRhcnktbWxkc2EiLCJ2ZXIiOiIyLjAiLCJhbmtfa3YiOjMsInRpZCI6IjdkM2E5YzFlLTRiMmYtNGU4YS05YzczLTI3NTAwMDAwMDAxMSIsImlhdCI6MTc5MDY1NjI0MH0\",\n      \"signature\" : \"U2VjcmV0YXJ5IE1MLURTQS02NSBzaWduYXR1cmUgb3ZlciB0aGUgcmVzb2x1dGlvbg\"\n    } ]\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies a JWS and reports the cryptographic verdict plus key metadata. Serialization is AUTO-DETECTED — both RFC 7515 §7.1 Compact (three dot-separated segments) and §7.2 JWS JSON Serialization inputs are accepted with no `serialization` parameter. Every key signs with ONE signature: a COMPOSITE signature is one value over the RFC 7515 signing input (the ML-DSA and classical component signatures concatenated), named by `kid`, `ank_kv` and the composite `alg` in its protected header; it is valid only when both components verify.  **A JWS signed by several keys.** A General JWS (RFC 7515 §7.2.1) may carry one signature per key, each naming its key in its own protected header; a composite key is one of them, with its one value. The token is first classified from its headers alone, before any key is looked up: a root member besides `payload` and `signatures`, a key named by two signatures, an HMAC `alg`, or more signatures than the deployment admits in one token is refused with 422, and signatures declaring different `b64` values with 400. Then every signer is gated in token order — every Capability Grant decision for `VERIFY` (a grant covering several signers is charged once), then every key-lifecycle decision on the `VERIFY` row at the version its `ank_kv` names (PRIMARY when it names none) — and the first refusal is a 403 that names no key and carries no verdict. Only then is each signature verified under its own key. `valid` is `true` only when EVERY signature verifies: a token with any failing signature is invalid, never a partial success.  **Response.** `signatureResults` carries one entry per signature, in token order — its `kid`, the key's catalogue `algorithm`, the `materialVersion` its key resolved to, and its own `verified` verdict. A JWS signed by one key answers one entry. No member names \"the\" key of the token.  **Qualified timestamp (JAdES B-T, informational).** When the verified JWS carries an embedded RFC 3161 qualified timestamp (JAdES `sigTst`), the response surfaces an informational `qualifiedTimestamp` block — `present`, `trustStatus` (VALID/SIGNATURE_INVALID/IMPRINT_MISMATCH/UNTRUSTED/REVOKED/EXPIRED), `genTime`, `serialNumber`, `policyOid`. The token is judged by checks in a fixed order and the first that fails decides `trustStatus`: the token parses and carries its signer's certificate (else `UNTRUSTED`); its own signature and certificate identifiers verify (else `SIGNATURE_INVALID`); its RFC 3161 message imprint declares SHA-256, SHA-384 or SHA-512 with absent or NULL parameters and a digest of that length (else `UNTRUSTED`); the imprint is the digest, under the token's own algorithm, of the ASCII signature value presented in this JWS (else `IMPRINT_MISMATCH` — the token time-stamps other bytes); only then is the TSA certificate judged, again first failure deciding: the signer's extended key usage (else `UNTRUSTED`), the signer's validity at `genTime` (else `EXPIRED`), a configured trust anchor (else `UNTRUSTED`), the path at `genTime` (else `EXPIRED` or `UNTRUSTED`; a signer that is itself a configured self-signed anchor passes here and skips the next check), and, only when the deployment checks revocation (the default), its revocation by RFC 3161 section 4 (else `REVOKED`, or `UNTRUSTED` when undetermined under the deployment's hard-fail revocation posture, the default); `VALID` when all pass, and `UNTRUSTED` when a certificate check cannot be completed at all. The token's age is not judged: its `genTime` was compared with the clock when the time-stamping authority's reply was received at signing, so a stamp verifies `VALID` however long ago it was issued. The three token fields are reported only for a verdict of the TSA-certificate checks, and are absent for every earlier one. Verification makes no call to the time-stamping authority and does not depend on the tenant's time-stamping settings. This block is purely informational and NEVER flips the boolean `valid`: a cryptographically valid signature with an absent, untrusted, or revoked timestamp still returns `valid = true`. The block is omitted for a compact or an unstamped JWS. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "COMPOSITE key (Ed25519+ML-DSA-44, one composite signature)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"jwsToken\" : {\n    \"payload\" : \"SGVsbG8gQW5rYQ\",\n    \"signatures\" : [ {\n      \"protected\" : \"eyJhbGciOiJNTC1EU0EtNDQtRWQyNTUxOSIsImtpZCI6Imludm9pY2Utc2lnbmVyLTIwMjUiLCJhbmtfa3YiOjEsImlhdCI6MTc5MDY0NzEwNn0\",\n      \"signature\" : \"DA3fv0AHKs1Zy4Z6gsTnoVfZU6qkGjTcUPP7RS7arzhtY_tbughY7Fq6dvNWXKioGsCbhsQrHyNvYPwPk9ja4yDYyimGKgApHesalAjjQGa1tlQOD6G2P2vLfOp1t6UBCQGeNb5MbQ-zynRqjmD6mIQf9xYfbDoT9kuMFVhdiAiO7J0sBND_VCG4gOkxAv-pIpyX8eYHEf_W5_2J5I3c9t3x_ej4-5LGAri6k81AQ8uXrRwTJeOn-DqTwOBv8Z91jwP5dTXfNnGzNaUdOP6rjDhw3YaptSWsgFGyMuBoZ13VLfihT0H5u1DEkJfCRy4Er8mxMYuGUhFvyXpsNPB10mJ9CK96u_EsL8RI291EsfijJNGU6Rxqsb6cTtd6kyGfEzYJofubxaPGGUBiLwNbISkgIRiL8sR_EK9M-1DUCj5lvO84UCJo6vpC5FNhCinXFuOst6_DGQfQYJ5etvkc0MTiyGFU01a-9n1Hs8FR46ch1cExq5SoTUeu22O2-CM2v8JBpodxW6kpIyIdKOLIL7-K2-ORR0EXR8LY_CdwRmE_8lpaFgfSyUeS8_V-CiHLb2jGc2BGlE5GO5WfwiZUp6TcV-9xdTcy8ID7qbvcONTxTOcVwrfGO-NZVoweXDHm6y5Aj-fpZQbbJboMY8fdT5LScHvjT87UbEz0q3RCGPuuyVmpwYf8wZdhcp-KCEYHYX6l0WAcVh9e4PLP0khLwY1Hex-uGXHUx9J2Hrq0SqV8jGNrz2iAwrEo8BU0gK7yISyPUFQ1z47gSBFzV0kXyi5Z79nRriwpCuANg_pCR5IdTC2QR2VRyNeaG-VT_IBLDkpsFiqISbHf83KTO7tuc7b95Qt2KSI6zEaJi27_sAZC-RPAdKHUogNqYsI9Px0f1l7o_r8w2TmZZPa8txEpg_BJQlIjCuh9jTmaiXoG835lb20VWs3qRWl3dKUI8CgMwa9c7pvrzR2hJHoxNF-RxVuKDt35ACSnJXLLjdcR4Ykp2sjKM3kuNntskTCS_FUDmMUQNa_Jqnt2484FphoTkF3xfgAIyPWi4Qzy99XlbaJ6IwCOwrrnpPd7HM3J6H5j3VhX0Fy5cCxgiDnCxtbx7qk0MY2ucy6oo2ojHI63_vkkSTZ-IvW3VdAEf1RcHPl5sxIBnzTsD3zRcPIASRytKKF_lGE1TVEk-3xepjNNnKzy7ivcf5hznV5YNuNVHL749tHgF50t0sZjj2JBTDQrt-KMZF3hSNyaljjmPJQXSInl35A-Fdy0ZbWTupl-OP1A4-PUR-6S1ztmYtmwocghkGPzz8qyfJHecG_4k1pSXJKeOIw501dkvk39ga5Fpza1fn_X-0CWSDUuJ-drVah-RvhhakilqUbFGUdB41kYmPMqRAllM4CY5wKLwqynSGf9Pa-UGPsPfZCZf8FR5hlKPbYOe8f_hY2Sm167g5nrq3xB4EX8fIR4xgTfS35CAZkRzYr264o7leR_i6TYv3VcFV0L2ySUOJ03N6gfdSgTkH-X9CgsQbVVxsXMbDT4f4jyuBT9DFwYYyGB6oym5287bVsV3JMJfqThABy4xw9-G9CAj4_93duRBTFxsofPN5XwlXtb4jlIWhCsV-_rK20ja5QE_Sy9etNSJaemWmokYV09pxOHP_phvkJO9NotnsFWxMkusQdYEgvp6Xg6ajAReMIardVkk_Lf_WGNy8kTtgfn2nbkxeeVciLXwDuq5SiEDAvXKrBEqQd5tcM5F9c9Br-7D_4HIk9k8MQgJFNA6eytDMstj4Z4GMXmHwkDy-IT_IdQc6WowIWZ7ADP-msRK3A7eapuHZ_WKgbDpYe_DDxkVxaXd6DHPBD74EmUS1kvrkOt-IxTcl1OOAN1DqjIsU-O33u4XARXuY20nvflfJhbD4PRgZMC_154riOWRN99I5MTsOgHNOZCmEwsEPhyQnQTC_ZQPF9xxcrKiwExGwStTV-HAX_M4HhIElpIhgkr0IgOH1I9GMC5yP1gtlIxCA82c1DQvT1l_tHA-nwmsJIXcGE3HyNNcdK8qKepyVTbzwuQtfAGVNWH8fEO494zsD8sRUtNSTIsX3snqNBzqliB8mXtPdA0SxLV0lkqkHQ1G5wGDfgGhkzIwkUnxShQn2uSKHpkC220z_p4RHcn2frkvWU8TgfXY0klhx0U1aAZ6yHYhW2NsHYFHiIGqMpScHkJ92_mPLc4OF-NaddHZJLNMNzN5BTB2wu_W_Yq5jmdb64IpNaN9-Md7_edU3htUGwHiuqcqIc5FMjzxZM3ehxPp0kqTLuNMcONhm4YHPWud1dN-ZmvCIVANNhmZC_tr4Pa5pS62BO1LuYn04eZ9MBggnS_j-CnqcN9vkh9oN-XadmNPY-MRHHEDp-e6Qx-Of4AjFNH8AzugG1ELcGM6n0_H3Xbq3b9eKELSPpdgP37FmHQCSLedsjDNeDWTd9-Mw0CrvXIH3008asmUGSD8abNZxLQQvcYk1LqVDvmzb6BUQDWNJY8zMGdetmKjL2T3rPoT00FC1cgDRxw4k2fX3q2FwkABlqiXmjK_Sw88kLV5YfZqSIPAEWLVfZC3fZjdb1QJDukpYM3K5bfLQyiAI2Y9fWBuMaTMzALYmTvGvlJztX5WzWKar_XGy4ZLYVjLY_MGarxuJChJiMBPmsFYmRbaw9XLjvxZVeoscU05JbVoDkQz7w31EYm7ZTtT1jmkf7DlLrvItMGNAr0TRuWtG4k2j7Q4JgzEAEea8SU7me9law2Uv0g5BdZdqJCLKsBxSUsw3A0w1XN2EdxE63CHu4Nj8bwaHVl1HO_1Y3ZxBzym7MQPb_o8Ep8XjTrPqhgwL3djIWACKTJsWU6am51QXNvxOGuUhjiYFX0FsrGZJeyOn6Yf4kpvIPMfP9uZ0lgMIFBAPSfeMy5PQXIIYERoXMG0CgIDzazVUr7Y5qfa1plxJLpxJQ9XsFcVyuTmKgkNs2mjhTnUguQ1N59Q4989WCaFNH0aJDBapfFoEuhvYIMLnppfIsLbJ58VO9vALiAjKoWQ3R_LS8cHuMuClCqkdlQ7yf6YC-qGqCLNDMqOAahLhblhjuVwC3J-pO_jahRo8Di3JSXvHrfCRrSDh7M40sQEilNW3uRoKSztLjJ0974BBghYWJjaHWEqLC0ur_L2-H2Ahc1OlteZnyCoLzIz9_l8fwFCUJZYmZndXqRkrnF2OPr-wAAAAAAAAAAAAAAABAiM0R2EnVgC05OvIWLpr22s7bSnheK2FoOmcWmTNt6wxb79PyRYeMFUzle-mUPh5-aF00dlow8WZXR7KsD9zYI6D8F\"\n    } ]\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Verifies a JWS and reports the cryptographic verdict plus key metadata. Serialization is AUTO-DETECTED — both RFC 7515 §7.1 Compact (three dot-separated segments) and §7.2 JWS JSON Serialization inputs are accepted with no `serialization` parameter. Every key signs with ONE signature: a COMPOSITE signature is one value over the RFC 7515 signing input (the ML-DSA and classical component signatures concatenated), named by `kid`, `ank_kv` and the composite `alg` in its protected header; it is valid only when both components verify.  **A JWS signed by several keys.** A General JWS (RFC 7515 §7.2.1) may carry one signature per key, each naming its key in its own protected header; a composite key is one of them, with its one value. The token is first classified from its headers alone, before any key is looked up: a root member besides `payload` and `signatures`, a key named by two signatures, an HMAC `alg`, or more signatures than the deployment admits in one token is refused with 422, and signatures declaring different `b64` values with 400. Then every signer is gated in token order — every Capability Grant decision for `VERIFY` (a grant covering several signers is charged once), then every key-lifecycle decision on the `VERIFY` row at the version its `ank_kv` names (PRIMARY when it names none) — and the first refusal is a 403 that names no key and carries no verdict. Only then is each signature verified under its own key. `valid` is `true` only when EVERY signature verifies: a token with any failing signature is invalid, never a partial success.  **Response.** `signatureResults` carries one entry per signature, in token order — its `kid`, the key's catalogue `algorithm`, the `materialVersion` its key resolved to, and its own `verified` verdict. A JWS signed by one key answers one entry. No member names \"the\" key of the token.  **Qualified timestamp (JAdES B-T, informational).** When the verified JWS carries an embedded RFC 3161 qualified timestamp (JAdES `sigTst`), the response surfaces an informational `qualifiedTimestamp` block — `present`, `trustStatus` (VALID/SIGNATURE_INVALID/IMPRINT_MISMATCH/UNTRUSTED/REVOKED/EXPIRED), `genTime`, `serialNumber`, `policyOid`. The token is judged by checks in a fixed order and the first that fails decides `trustStatus`: the token parses and carries its signer's certificate (else `UNTRUSTED`); its own signature and certificate identifiers verify (else `SIGNATURE_INVALID`); its RFC 3161 message imprint declares SHA-256, SHA-384 or SHA-512 with absent or NULL parameters and a digest of that length (else `UNTRUSTED`); the imprint is the digest, under the token's own algorithm, of the ASCII signature value presented in this JWS (else `IMPRINT_MISMATCH` — the token time-stamps other bytes); only then is the TSA certificate judged, again first failure deciding: the signer's extended key usage (else `UNTRUSTED`), the signer's validity at `genTime` (else `EXPIRED`), a configured trust anchor (else `UNTRUSTED`), the path at `genTime` (else `EXPIRED` or `UNTRUSTED`; a signer that is itself a configured self-signed anchor passes here and skips the next check), and, only when the deployment checks revocation (the default), its revocation by RFC 3161 section 4 (else `REVOKED`, or `UNTRUSTED` when undetermined under the deployment's hard-fail revocation posture, the default); `VALID` when all pass, and `UNTRUSTED` when a certificate check cannot be completed at all. The token's age is not judged: its `genTime` was compared with the clock when the time-stamping authority's reply was received at signing, so a stamp verifies `VALID` however long ago it was issued. The three token fields are reported only for a verdict of the TSA-certificate checks, and are absent for every earlier one. Verification makes no call to the time-stamping authority and does not depend on the tenant's time-stamping settings. This block is purely informational and NEVER flips the boolean `valid`: a cryptographically valid signature with an absent, untrusted, or revoked timestamp still returns `valid = true`. The block is omitted for a compact or an unstamped JWS. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": " Key Query",
	            "description": "Retrieve key metadata and list stored keys.",
	            "item": [
	                        {
    "name": "/api/v3/key-management/keys",
                "description": " Retrieves ONE PAGE of the tenant's keys. Secret fields (e.g. privateKey)  are omitted. Filters (origin/restricted/kty/status) apply server-side  BEFORE pagination: totalElements is the filtered count. size is capped  at 200 (400 on violation, never clamped). A page beyond the last page  yields an empty content array with the true totals (HTTP 200).   **Population.** Without a status filter the page holds every key the  tenant still holds, in whatever lifecycle state it is in: active,  expired, suspended, revoked, archived and pending_destruction alike, each  with its own status. A destroyed key is not among them. It is returned  only when status=deleted_logical is requested, as a Deleted-view row  carrying kid, uuid, status, createdAt and deletedAt, and no algorithm,  key type, key operations, usage, origin or exportability.   **Telling rows apart.** A kid can be taken again after its key is  destroyed, so the Deleted view can return a row sharing its kid with a  live key, or several rows sharing one kid. uuid is the key's own identity,  never reused, and is the member that tells such rows apart.  ",
                 "item": [
                            {
                                "name": "List keys (paginated, no secret data).",
                                "request": {
    "method": "GET",
    "header": [
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/key-management/keys",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "key-management",
        "keys"
    ],
    "variable": [
    ],
    "query": [
        {
        "key": "origin",
        "value": "origin_example",
        "description": "Filter by key origin, using the SAME token a key's `origin` field carries in the response. Absent or empty means no filter. Any other value is rejected with 400.",
        "disabled": true
        },
        {
        "key": "restricted",
        "value": "true",
        "description": "Filter by restriction status",
        "disabled": true
        },
        {
        "key": "kty",
        "value": "kty_example",
        "description": "Filter by key type, using the SAME token a key's `kty` field carries in the response: `ML-KEM`, `ML-DSA`, `SLH-DSA`, `FALCON`, `XMSS`, `LMS`, `HQC`, `FRODO`, `CMCE`, `BIKE`, `SABER`, `NTRU`, `NTRUPRIME`, `SMAUG-T`, `RSA`, `EC`, `OKP`, `oct`, `SM2`, `GOST-EC`, and `COMPOSITE` for every hybrid pairing. A composite key publishes one coarse token; its pairing is named by `alg` and its construction by `compositeMode`. Absent or empty means no filter. Any other value is rejected with 400.",
        "disabled": true
        },
        {
        "key": "status",
        "value": "status_example",
        "description": "Filter by key lifecycle status, using the SAME token a key's `status` field carries in the response: `active`, `pending_rotation`, `rotated`, `expired`, `revoked`, `archived`, `deleted_logical`, `suspended`, `pending_destruction`. Absent or empty means no filter. Any other value is rejected with 400.",
        "disabled": true
        },
        {
        "key": "page",
        "value": "0",
        "description": "Zero-based page index.",
        "disabled": true
        },
        {
        "key": "size",
        "value": "50",
        "description": "Page size (1..200). Values above 200 are REJECTED with 400, never clamped.",
        "disabled": true
        }
    ]
    },
    "description": " Retrieves ONE PAGE of the tenant's keys. Secret fields (e.g. privateKey)  are omitted. Filters (origin/restricted/kty/status) apply server-side  BEFORE pagination: totalElements is the filtered count. size is capped  at 200 (400 on violation, never clamped). A page beyond the last page  yields an empty content array with the true totals (HTTP 200).   **Population.** Without a status filter the page holds every key the  tenant still holds, in whatever lifecycle state it is in: active,  expired, suspended, revoked, archived and pending_destruction alike, each  with its own status. A destroyed key is not among them. It is returned  only when status=deleted_logical is requested, as a Deleted-view row  carrying kid, uuid, status, createdAt and deletedAt, and no algorithm,  key type, key operations, usage, origin or exportability.   **Telling rows apart.** A kid can be taken again after its key is  destroyed, so the Deleted view can return a row sharing its kid with a  live key, or several rows sharing one kid. uuid is the key's own identity,  never reused, and is the member that tells such rows apart.  "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/key-management/keys/:kid/metadata",
                "description": "Returns comprehensive metadata for a single key including: - Lifecycle information (status, created/expires timestamps) - Usage tracking (usage count, limits) - Algorithm details (kty, alg) - Capability flags (exportable, origin, restricted, keyOps)  This endpoint is suitable for administrative dashboards, key inventory systems, and compliance audits where cryptographic material exposure is unnecessary.  **Note**: To retrieve the public key material, use the administration API's export endpoint GET /api/v3/admin/tenants/{tenantId}/keys/{kid}/export which enforces exportable flag validation. ",
                 "item": [
                            {
                                "name": "Retrieve key metadata (no cryptographic material)",
                                "request": {
    "method": "GET",
    "header": [
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/key-management/keys/:kid/metadata",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "key-management",
        "keys",
        ":kid",
        "metadata"
    ],
    "variable": [
        {
        "key": "kid",
        "value": "",
        "description": "Key identifier"
        }
    ],
    "query": [
    ]
    },
    "description": "Returns comprehensive metadata for a single key including: - Lifecycle information (status, created/expires timestamps) - Usage tracking (usage count, limits) - Algorithm details (kty, alg) - Capability flags (exportable, origin, restricted, keyOps)  This endpoint is suitable for administrative dashboards, key inventory systems, and compliance audits where cryptographic material exposure is unnecessary.  **Note**: To retrieve the public key material, use the administration API's export endpoint GET /api/v3/admin/tenants/{tenantId}/keys/{kid}/export which enforces exportable flag validation. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": "License Metrics",
	            "description": "Operational metrics for license validation monitoring",
	            "item": [
	                        {
    "name": "/api/v3/license/metrics",
                "description": "Returns license validation counters, including the percentage of requests validated strictly vs allowed without validation. Useful for monitoring service availability vs enforcement tradeoff. The figures are those of the instance of this service that answered this request; they are not aggregated across instances, so two calls may return the counters of different instances. Only `unvalidatedRequestsAllowed` has a deployment-wide counterpart: the per-instance meter `ankasecure.license.grace{outcome=admitted}`, summed across instances. `strictlyValidatedRequests`, `validationRate`, `staleVerdictsServed` and `maxStalenessRefusals` are per instance, and no meter sums them.",
                 "item": [
                            {
                                "name": "Get license validation metrics",
                                "request": {
    "method": "GET",
    "header": [
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/license/metrics",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "license",
        "metrics"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Returns license validation counters, including the percentage of requests validated strictly vs allowed without validation. Useful for monitoring service availability vs enforcement tradeoff. The figures are those of the instance of this service that answered this request; they are not aggregated across instances, so two calls may return the counters of different instances. Only `unvalidatedRequestsAllowed` has a deployment-wide counterpart: the per-instance meter `ankasecure.license.grace{outcome=admitted}`, summed across instances. `strictlyValidatedRequests`, `validationRate`, `staleVerdictsServed` and `maxStalenessRefusals` are per instance, and no meter sums them."
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": "Migration",
	            "description": "Migration operations for legacy PKCS#7/CMS data: analysis of a PKCS#7 structure and\nits conversion to JOSE under keys the tenant already holds. These endpoints support\ntransitioning legacy cryptographic assets to ANKASecure's post-quantum infrastructure.\n",
	            "item": [
	                        {
    "name": "/api/v3/migration/analyze-pkcs7",
                "description": "Introspects PKCS#7/CMS binary data and returns structured metadata including signers, recipients, algorithms, certificates, and conversion feasibility.  Supports SignedData, EnvelopedData and SignedAndEnvelopedData (RFC 2315 section 11, whose signers are read from the outer `signerInfos`). Nothing is decrypted, no certificate path or timestamp is validated and no key is needed, so `pkcs7Data` is the whole request.  **Every actor is reported.** `signers` and `recipients` list each one in encoded order, and the count of either never makes the structure unsupported:  - `recommendations.migrationPath` is the JOSE form a conversion under   `serialization` AUTO produces — `_COMPACT` for at most one signer and at most one   recipient, `_JSON` (General JSON serialization, RFC 7515 section 7.2.1 /   RFC 7516 section 7.2.1) otherwise. - `recommendations.requiredKeys` names every signer (`signing`) and every recipient   (`encryption`) by the issuer and serial number the tenant key's certificate must   carry. For an encrypted structure, `decryptionRequirement` states that the private   key of one recipient is needed as well. - `supportStatus` runs every check a conversion runs WITHOUT a key and reports each   refusal with the conversion's own code, so `supported` is false exactly when the   conversion would refuse the structure before any key: `ACTOR_LIMIT_EXCEEDED`; a   SignedAndEnvelopedData with no outer signer (`SIGNED_AND_ENVELOPED_WITHOUT_SIGNER`),   a non-RSA outer signer (`UNSUPPORTED_SIGNED_AND_ENVELOPED_SIGNER_KEY`), a plain-form   encryptedDigest (`SIGNED_AND_ENVELOPED_DIGEST_NOT_ENCRYPTED`) or a content cipher it   does not decrypt (`UNSUPPORTED_CONTENT_ENCRYPTION`); and `INVALID_PKCS7` for what   the conversion answers 400 `invalid-pkcs7` (a SignedData with no signer or no   encapsulated content). A SHA-1/MD5 signer is `LEGACY_ALGORITHM_REJECTED` with   severity WARNING: the conversion refuses it unless `algorithmPolicy.allowLegacyHash`   is true. An RFC 3161 timestamp is reported as `TIMESTAMP_DETECTED` (INFO). - `limits.maxActors` is that bound: the most signers and recipients, together, one   conversion accepts. It is the crypto plane's one actor bound, the value the   conversion enforces and the same one a multi-key JOSE token is held to, published   here so a client knows it before converting. ",
                 "item": [
                            {
                                "name": "Analyze a SignedData file",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"pkcs7Data\" : \"MIIGHgYJKoZIhvcNAQcCoIIGDzCCBgsCAQAxggE...\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/analyze-pkcs7",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "analyze-pkcs7"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Introspects PKCS#7/CMS binary data and returns structured metadata including signers, recipients, algorithms, certificates, and conversion feasibility.  Supports SignedData, EnvelopedData and SignedAndEnvelopedData (RFC 2315 section 11, whose signers are read from the outer `signerInfos`). Nothing is decrypted, no certificate path or timestamp is validated and no key is needed, so `pkcs7Data` is the whole request.  **Every actor is reported.** `signers` and `recipients` list each one in encoded order, and the count of either never makes the structure unsupported:  - `recommendations.migrationPath` is the JOSE form a conversion under   `serialization` AUTO produces — `_COMPACT` for at most one signer and at most one   recipient, `_JSON` (General JSON serialization, RFC 7515 section 7.2.1 /   RFC 7516 section 7.2.1) otherwise. - `recommendations.requiredKeys` names every signer (`signing`) and every recipient   (`encryption`) by the issuer and serial number the tenant key's certificate must   carry. For an encrypted structure, `decryptionRequirement` states that the private   key of one recipient is needed as well. - `supportStatus` runs every check a conversion runs WITHOUT a key and reports each   refusal with the conversion's own code, so `supported` is false exactly when the   conversion would refuse the structure before any key: `ACTOR_LIMIT_EXCEEDED`; a   SignedAndEnvelopedData with no outer signer (`SIGNED_AND_ENVELOPED_WITHOUT_SIGNER`),   a non-RSA outer signer (`UNSUPPORTED_SIGNED_AND_ENVELOPED_SIGNER_KEY`), a plain-form   encryptedDigest (`SIGNED_AND_ENVELOPED_DIGEST_NOT_ENCRYPTED`) or a content cipher it   does not decrypt (`UNSUPPORTED_CONTENT_ENCRYPTION`); and `INVALID_PKCS7` for what   the conversion answers 400 `invalid-pkcs7` (a SignedData with no signer or no   encapsulated content). A SHA-1/MD5 signer is `LEGACY_ALGORITHM_REJECTED` with   severity WARNING: the conversion refuses it unless `algorithmPolicy.allowLegacyHash`   is true. An RFC 3161 timestamp is reported as `TIMESTAMP_DETECTED` (INFO). - `limits.maxActors` is that bound: the most signers and recipients, together, one   conversion accepts. It is the crypto plane's one actor bound, the value the   conversion enforces and the same one a multi-key JOSE token is held to, published   here so a client knows it before converting. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/migration/convert-pkcs7-to-jose",
                "description": "Converts legacy PKCS#7/CMS files to modern JOSE (JWE/JWS) format.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → JWS with one signature per signer key - EnvelopedData (M recipients) → JWE with one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE   whose plaintext is a JWS with one signature per outer signer key  A kid names ONE entry: two SignerInfos (or two RecipientInfos) that resolve to the same tenant key produce one signature (or one recipient) for that key, and both actors are reported against it in `signers[]` / `recipients[]`.  **Serialization** (`serialization`, exact case):  - `AUTO` (default): Compact (RFC 7515 section 7.1 / RFC 7516 section 7.1) for at most one   signer and at most one recipient; General JSON (RFC 7515 section 7.2.1 / RFC 7516   section 7.2.1) otherwise, on both layers of a nested result. - `COMPACT`: Compact; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` before any key is looked up. - `JSON`: General JSON serialization, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`.  **Process** (every refusal precedes the first use of a private key, except the three that need the decrypting recipient's key: a decryption failure, an outer SignedAndEnvelopedData signer that does not verify, and SignedAndEnvelopedData content-encryption parameters the named cipher cannot use):  1. Parse the PKCS#7 structure; refuse an unidentifiable actor or more actors than one    conversion accepts (`ACTOR_LIMIT_EXCEEDED`) 2. Check `serialization` against the actor counts, and refuse a legacy SHA-1/MD5 signer    unless `algorithmPolicy.allowLegacyHash` is true 3. Verify the CMS signature of every signer of a SignedData — always (the outer    signers of a SignedAndEnvelopedData are verified in step 6, under the    content-encryption key, before anything is signed) 4. Resolve every signer and recipient to a tenant key by issuer and serial number; one    422 names every actor without one (`unresolvedActors`) 5. Admit every key-lifecycle leg (decrypt, encrypt per recipient, sign per signer) 6. Decrypt once with one recipient's private key (the `decryptionKid` recipient, or the    first recipient in encoded order whose key admits decryption), then re-sign and    re-encrypt  **Prerequisites:** Import the signer and recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore. POST /api/v3/migration/analyze-pkcs7 lists every key the file needs.  **Next steps:** the token can be taken to PQC algorithms with POST /api/v3/crypto/reencrypt or POST /api/v3/crypto/resign. A token with several recipients or several signatures is accepted there as it is: `sourceKid` names the recipient, or the signature, that is replaced, and every other entry is kept. ",
                 "item": [
                            {
                                "name": "SignedData with three signers (AUTO: General JSON JWS)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"pkcs7Data\" : \"MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwGggCSABIIB...\",\n  \"serialization\" : \"AUTO\",\n  \"targetFormat\" : \"AUTO\",\n  \"algorithmPolicy\" : {\n    \"allowLegacyHash\" : false\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/convert-pkcs7-to-jose",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "convert-pkcs7-to-jose"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Converts legacy PKCS#7/CMS files to modern JOSE (JWE/JWS) format.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → JWS with one signature per signer key - EnvelopedData (M recipients) → JWE with one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE   whose plaintext is a JWS with one signature per outer signer key  A kid names ONE entry: two SignerInfos (or two RecipientInfos) that resolve to the same tenant key produce one signature (or one recipient) for that key, and both actors are reported against it in `signers[]` / `recipients[]`.  **Serialization** (`serialization`, exact case):  - `AUTO` (default): Compact (RFC 7515 section 7.1 / RFC 7516 section 7.1) for at most one   signer and at most one recipient; General JSON (RFC 7515 section 7.2.1 / RFC 7516   section 7.2.1) otherwise, on both layers of a nested result. - `COMPACT`: Compact; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` before any key is looked up. - `JSON`: General JSON serialization, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`.  **Process** (every refusal precedes the first use of a private key, except the three that need the decrypting recipient's key: a decryption failure, an outer SignedAndEnvelopedData signer that does not verify, and SignedAndEnvelopedData content-encryption parameters the named cipher cannot use):  1. Parse the PKCS#7 structure; refuse an unidentifiable actor or more actors than one    conversion accepts (`ACTOR_LIMIT_EXCEEDED`) 2. Check `serialization` against the actor counts, and refuse a legacy SHA-1/MD5 signer    unless `algorithmPolicy.allowLegacyHash` is true 3. Verify the CMS signature of every signer of a SignedData — always (the outer    signers of a SignedAndEnvelopedData are verified in step 6, under the    content-encryption key, before anything is signed) 4. Resolve every signer and recipient to a tenant key by issuer and serial number; one    422 names every actor without one (`unresolvedActors`) 5. Admit every key-lifecycle leg (decrypt, encrypt per recipient, sign per signer) 6. Decrypt once with one recipient's private key (the `decryptionKid` recipient, or the    first recipient in encoded order whose key admits decryption), then re-sign and    re-encrypt  **Prerequisites:** Import the signer and recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore. POST /api/v3/migration/analyze-pkcs7 lists every key the file needs.  **Next steps:** the token can be taken to PQC algorithms with POST /api/v3/crypto/reencrypt or POST /api/v3/crypto/resign. A token with several recipients or several signatures is accepted there as it is: `sourceKid` names the recipient, or the signature, that is replaced, and every other entry is kept. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "EnvelopedData with two recipients, decrypting recipient named",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"pkcs7Data\" : \"MIIGHgYJKoZIhvcNAQcDoIIGDzCCBgsCAQAxggE...\",\n  \"decryptionKid\" : \"treasury-archive-rsa-2019\",\n  \"serialization\" : \"AUTO\",\n  \"targetFormat\" : \"AUTO\"\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/convert-pkcs7-to-jose",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "convert-pkcs7-to-jose"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Converts legacy PKCS#7/CMS files to modern JOSE (JWE/JWS) format.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → JWS with one signature per signer key - EnvelopedData (M recipients) → JWE with one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE   whose plaintext is a JWS with one signature per outer signer key  A kid names ONE entry: two SignerInfos (or two RecipientInfos) that resolve to the same tenant key produce one signature (or one recipient) for that key, and both actors are reported against it in `signers[]` / `recipients[]`.  **Serialization** (`serialization`, exact case):  - `AUTO` (default): Compact (RFC 7515 section 7.1 / RFC 7516 section 7.1) for at most one   signer and at most one recipient; General JSON (RFC 7515 section 7.2.1 / RFC 7516   section 7.2.1) otherwise, on both layers of a nested result. - `COMPACT`: Compact; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` before any key is looked up. - `JSON`: General JSON serialization, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`.  **Process** (every refusal precedes the first use of a private key, except the three that need the decrypting recipient's key: a decryption failure, an outer SignedAndEnvelopedData signer that does not verify, and SignedAndEnvelopedData content-encryption parameters the named cipher cannot use):  1. Parse the PKCS#7 structure; refuse an unidentifiable actor or more actors than one    conversion accepts (`ACTOR_LIMIT_EXCEEDED`) 2. Check `serialization` against the actor counts, and refuse a legacy SHA-1/MD5 signer    unless `algorithmPolicy.allowLegacyHash` is true 3. Verify the CMS signature of every signer of a SignedData — always (the outer    signers of a SignedAndEnvelopedData are verified in step 6, under the    content-encryption key, before anything is signed) 4. Resolve every signer and recipient to a tenant key by issuer and serial number; one    422 names every actor without one (`unresolvedActors`) 5. Admit every key-lifecycle leg (decrypt, encrypt per recipient, sign per signer) 6. Decrypt once with one recipient's private key (the `decryptionKid` recipient, or the    first recipient in encoded order whose key admits decryption), then re-sign and    re-encrypt  **Prerequisites:** Import the signer and recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore. POST /api/v3/migration/analyze-pkcs7 lists every key the file needs.  **Next steps:** the token can be taken to PQC algorithms with POST /api/v3/crypto/reencrypt or POST /api/v3/crypto/resign. A token with several recipients or several signatures is accepted there as it is: `sourceKid` names the recipient, or the signature, that is replaced, and every other entry is kept. "
}
                                ,"response": [
                            ]
                            },
                            {
                                "name": "SignedAndEnvelopedData with one signer and one recipient (COMPACT)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "application/json",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "{\n  \"pkcs7Data\" : \"MIIHkwYJKoZIhvcNAQcEoIIHhDCCB4ACAQExggE...\",\n  \"serialization\" : \"COMPACT\",\n  \"targetFormat\" : \"AUTO\",\n  \"algorithmPolicy\" : {\n    \"allowLegacyHash\" : false\n  }\n}",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/convert-pkcs7-to-jose",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "convert-pkcs7-to-jose"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Converts legacy PKCS#7/CMS files to modern JOSE (JWE/JWS) format.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → JWS with one signature per signer key - EnvelopedData (M recipients) → JWE with one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE   whose plaintext is a JWS with one signature per outer signer key  A kid names ONE entry: two SignerInfos (or two RecipientInfos) that resolve to the same tenant key produce one signature (or one recipient) for that key, and both actors are reported against it in `signers[]` / `recipients[]`.  **Serialization** (`serialization`, exact case):  - `AUTO` (default): Compact (RFC 7515 section 7.1 / RFC 7516 section 7.1) for at most one   signer and at most one recipient; General JSON (RFC 7515 section 7.2.1 / RFC 7516   section 7.2.1) otherwise, on both layers of a nested result. - `COMPACT`: Compact; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` before any key is looked up. - `JSON`: General JSON serialization, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`.  **Process** (every refusal precedes the first use of a private key, except the three that need the decrypting recipient's key: a decryption failure, an outer SignedAndEnvelopedData signer that does not verify, and SignedAndEnvelopedData content-encryption parameters the named cipher cannot use):  1. Parse the PKCS#7 structure; refuse an unidentifiable actor or more actors than one    conversion accepts (`ACTOR_LIMIT_EXCEEDED`) 2. Check `serialization` against the actor counts, and refuse a legacy SHA-1/MD5 signer    unless `algorithmPolicy.allowLegacyHash` is true 3. Verify the CMS signature of every signer of a SignedData — always (the outer    signers of a SignedAndEnvelopedData are verified in step 6, under the    content-encryption key, before anything is signed) 4. Resolve every signer and recipient to a tenant key by issuer and serial number; one    422 names every actor without one (`unresolvedActors`) 5. Admit every key-lifecycle leg (decrypt, encrypt per recipient, sign per signer) 6. Decrypt once with one recipient's private key (the `decryptionKid` recipient, or the    first recipient in encoded order whose key admits decryption), then re-sign and    re-encrypt  **Prerequisites:** Import the signer and recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore. POST /api/v3/migration/analyze-pkcs7 lists every key the file needs.  **Next steps:** the token can be taken to PQC algorithms with POST /api/v3/crypto/reencrypt or POST /api/v3/crypto/resign. A token with several recipients or several signatures is accepted there as it is: `sourceKid` names the recipient, or the signature, that is replaced, and every other entry is kept. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/migration/stream/analyze-pkcs7",
                "description": "Introspects PKCS#7/CMS binary data of ANY size and returns structured metadata, parsing incrementally.  Returns metadata including signers, recipients, algorithms, certificates, and conversion feasibility.  **Supports** SignedData, EnvelopedData and SignedAndEnvelopedData (RFC 2315 section 11, whose signers are read from the outer `signerInfos`), with any number of signers and recipients. The response is the one POST /api/v3/migration/analyze-pkcs7 answers for the same file: `supportStatus`, `recommendations.migrationPath` and `recommendations.requiredKeys` are equal on the two routes. Nothing is decrypted and no key is needed.  **Input:** multipart/form-data with a `metadata` part followed by a `file` part (binary PKCS#7).  **Part order is enforced**, as on every other streaming endpoint: `metadata` MUST precede `file`. The parse is sequential and single-pass, so the payload cannot be reached without consuming what precedes it and there is nothing to go back to; a `file`-first body is refused with `400 .../errors/multipart-part-order` before any payload byte is read. ",
                 "item": [
                            {
                                "name": "Analyze PKCS#7 structure (streaming, >5MB files)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/stream/analyze-pkcs7",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "stream",
        "analyze-pkcs7"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Introspects PKCS#7/CMS binary data of ANY size and returns structured metadata, parsing incrementally.  Returns metadata including signers, recipients, algorithms, certificates, and conversion feasibility.  **Supports** SignedData, EnvelopedData and SignedAndEnvelopedData (RFC 2315 section 11, whose signers are read from the outer `signerInfos`), with any number of signers and recipients. The response is the one POST /api/v3/migration/analyze-pkcs7 answers for the same file: `supportStatus`, `recommendations.migrationPath` and `recommendations.requiredKeys` are equal on the two routes. Nothing is decrypted and no key is needed.  **Input:** multipart/form-data with a `metadata` part followed by a `file` part (binary PKCS#7).  **Part order is enforced**, as on every other streaming endpoint: `metadata` MUST precede `file`. The parse is sequential and single-pass, so the payload cannot be reached without consuming what precedes it and there is nothing to go back to; a `file`-first body is refused with `400 .../errors/multipart-part-order` before any payload byte is read. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/migration/stream/convert-pkcs7-to-jose",
                "description": "Converts PKCS#7/CMS files of any size to modern JOSE (JWE/JWS), streaming the result.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → detached JWS (RFC 7797), one signature per signer key - EnvelopedData (M recipients) → JWE carried as multipart/mixed, one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE whose   plaintext is an **attached** JWS with one signature per outer signer key  **Serialization** (`serialization`, exact case; detached streaming output is always JSON-serialized, so the single-actor form is not RFC 7515 section 7.1 Compact):  - `AUTO` (default): the single-actor form for at most one signer and at most one   recipient (a flattened detached JWS; the multipart JWE with a one-recipient header);   General otherwise (a `signatures` array; a `recipients` array). - `COMPACT`: the single-actor form; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` and zero body bytes. - `JSON`: General, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`, before the upload is read.  **Response format varies by PKCS#7 type:**  **SignedData** returns `application/octet-stream`; one signer under AUTO: ```json {\"protected\":\"eyJhbGc...\",\"signature\":\"dGVz...\"} ``` Two signers: ```json {\"signatures\":[{\"protected\":\"eyJhbGc...\",\"signature\":\"dGVz...\"},{\"protected\":\"eyJhbGc...\",\"signature\":\"c2ln...\"}]} ```  **EnvelopedData** returns `multipart/mixed`: ``` ------ankatech-<UUID> Content-Type: application/jose+json  {\"protected\":\"...\",\"recipients\":[...],\"iv\":\"...\"}  ------ankatech-<UUID> Content-Type: application/octet-stream  <binary ciphertext stream> ------ankatech-<UUID>-- ```  **Size and cost:**  - There is no size limit on the uploaded file. - EnvelopedData is converted in a single pass with bounded memory, whatever the number   of recipients. - The signed shapes read the uploaded file once per signer plus once more, because   RFC 2315 places the signer metadata after the content and each signature is computed   in its own pass: SignedData costs **N + 1** passes, SignedAndEnvelopedData **N + 3**   (a keyless structure pass, a verification pass, one signing pass per signer and the   emission). Expect the wall-clock time to scale with the signer count.  **Abort contract:** every failure that can be decided before the first payload byte is answered as an HTTP status with an `application/problem+json` document. A failure raised while the output is being emitted is answered the same way while the response is still uncommitted (its bytes have not left the server's response buffer); once the response is committed, a failure ends the response **without completing its framing** and no problem document is written into the body — so a response that stops short is a failure, not a truncated success.  **Important:** - Response does NOT include metadata (signers, recipients, algorithm details) - For metadata: Use POST /api/v3/migration/stream/analyze-pkcs7 first - The output is an input POST /api/v3/crypto/stream/reencrypt and   /crypto/stream/resign accept. For an output with several recipients or several   signatures, `sourceKid` names the recipient, or the signature, that is replaced,   and every other entry is kept.  **Prerequisites:** Import signer/recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore  **Input:** multipart/form-data with 'metadata' (JSON) and 'file' (binary PKCS#7) ",
                 "item": [
                            {
                                "name": "Convert PKCS#7 to JOSE (streaming)",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "*/*",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/migration/stream/convert-pkcs7-to-jose",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "migration",
        "stream",
        "convert-pkcs7-to-jose"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Converts PKCS#7/CMS files of any size to modern JOSE (JWE/JWS), streaming the result.  This is a **format conversion** (PKCS#7 container → JOSE container), not an algorithm conversion. Classical algorithms (RSA, ECDSA, AES) are preserved or upgraded (CBC→GCM).  **Supported conversions** — every signer and every recipient of the input is carried:  - SignedData (N signers) → detached JWS (RFC 7797), one signature per signer key - EnvelopedData (M recipients) → JWE carried as multipart/mixed, one recipient per recipient key - SignedAndEnvelopedData (RFC 2315 section 11: N outer signers, M recipients) → JWE whose   plaintext is an **attached** JWS with one signature per outer signer key  **Serialization** (`serialization`, exact case; detached streaming output is always JSON-serialized, so the single-actor form is not RFC 7515 section 7.1 Compact):  - `AUTO` (default): the single-actor form for at most one signer and at most one   recipient (a flattened detached JWS; the multipart JWE with a one-recipient header);   General otherwise (a `signatures` array; a `recipients` array). - `COMPACT`: the single-actor form; more than one signer or recipient is refused with 422   `INCOMPATIBLE_SERIALIZATION` and zero body bytes. - `JSON`: General, also for a single actor.  Any other value is refused with 400 `invalid-input` naming `serialization`, before the upload is read.  **Response format varies by PKCS#7 type:**  **SignedData** returns `application/octet-stream`; one signer under AUTO: ```json {\"protected\":\"eyJhbGc...\",\"signature\":\"dGVz...\"} ``` Two signers: ```json {\"signatures\":[{\"protected\":\"eyJhbGc...\",\"signature\":\"dGVz...\"},{\"protected\":\"eyJhbGc...\",\"signature\":\"c2ln...\"}]} ```  **EnvelopedData** returns `multipart/mixed`: ``` ------ankatech-<UUID> Content-Type: application/jose+json  {\"protected\":\"...\",\"recipients\":[...],\"iv\":\"...\"}  ------ankatech-<UUID> Content-Type: application/octet-stream  <binary ciphertext stream> ------ankatech-<UUID>-- ```  **Size and cost:**  - There is no size limit on the uploaded file. - EnvelopedData is converted in a single pass with bounded memory, whatever the number   of recipients. - The signed shapes read the uploaded file once per signer plus once more, because   RFC 2315 places the signer metadata after the content and each signature is computed   in its own pass: SignedData costs **N + 1** passes, SignedAndEnvelopedData **N + 3**   (a keyless structure pass, a verification pass, one signing pass per signer and the   emission). Expect the wall-clock time to scale with the signer count.  **Abort contract:** every failure that can be decided before the first payload byte is answered as an HTTP status with an `application/problem+json` document. A failure raised while the output is being emitted is answered the same way while the response is still uncommitted (its bytes have not left the server's response buffer); once the response is committed, a failure ends the response **without completing its framing** and no problem document is written into the body — so a response that stops short is a failure, not a truncated success.  **Important:** - Response does NOT include metadata (signers, recipients, algorithm details) - For metadata: Use POST /api/v3/migration/stream/analyze-pkcs7 first - The output is an input POST /api/v3/crypto/stream/reencrypt and   /crypto/stream/resign accept. For an output with several recipients or several   signatures, `sourceKid` names the recipient, or the signature, that is replaced,   and every other entry is kept.  **Prerequisites:** Import signer/recipient keys via POST /api/v3/admin/tenants/{tenantId}/keys/import-keystore  **Input:** multipart/form-data with 'metadata' (JSON) and 'file' (binary PKCS#7) "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": "Crypto Limits",
	            "description": "Discovery of the crypto payload limit (read-only)",
	            "item": [
	                        {
    "name": "/api/v3/crypto/limits",
                "description": "Returns the maximum plaintext byte length the producer crypto endpoints (encrypt / sign / sign-encrypt) accept for the calling tenant. Resolved from the same single source of truth, for the same tenant, that the encrypt gate enforces, so the advertised value never drifts from the enforced one. The operator sets it on the deployment plane and it applies without a restart.",
                 "item": [
                            {
                                "name": "Discover the crypto plaintext limit",
                                "request": {
    "method": "GET",
    "header": [
        {
        "key": "Accept",
        "value": "application/json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/crypto/limits",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "crypto",
        "limits"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Returns the maximum plaintext byte length the producer crypto endpoints (encrypt / sign / sign-encrypt) accept for the calling tenant. Resolved from the same single source of truth, for the same tenant, that the encrypt gate enforces, so the advertised value never drifts from the enforced one. The operator sets it on the deployment plane and it applies without a restart."
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        },
	        {
	            "name": "Interoperability",
	            "description": "Continuous interoperability operations for cryptographic collaboration with\nexternal systems using caller-supplied keys (not persisted in keystore).\nSupports signature verification and encryption for cross-platform integration\nwithout importing keys into ANKASecure infrastructure.\n",
	            "item": [
	                        {
    "name": "/api/v3/interoperability/encrypt",
                "description": "Accepts two multipart parts: • <code>metadata</code> – JSON (<em>CryptoUtilityApi</em>) with   <code>kty</code>, <code>alg</code>, <code>publicKey</code> • <code>file</code> – binary plaintext Returns a streaming <code>application/octet-stream</code> response without persisting the key. ",
                 "item": [
                            {
                                "name": "Encrypt data with a provided public key (stream).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/interoperability/encrypt",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "interoperability",
        "encrypt"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Accepts two multipart parts: • <code>metadata</code> – JSON (<em>CryptoUtilityApi</em>) with   <code>kty</code>, <code>alg</code>, <code>publicKey</code> • <code>file</code> – binary plaintext Returns a streaming <code>application/octet-stream</code> response without persisting the key. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        },
	                        {
    "name": "/api/v3/interoperability/verify",
                "description": "Accepts two multipart parts: • <code>metadata</code> – JSON (<em>SignatureUtilityApi</em>)   containing the caller's detached-JWS object (<code>signatureBase64</code>)   <strong>and</strong> the corresponding <code>publicKey</code>. • <code>file</code> – the raw payload that was signed.  The controller ignores any <code>kid</code> inside the JWS header and uses the public key supplied by the caller for streaming verification. It answers 200 with a <em>VerifySignatureResponse</em> carrying <code>valid</code> (<code>true</code> or <code>false</code>) and one <code>signatureResults</code> entry for the one signature the supplied key verifies: its <code>algorithm</code> is the one the caller declared, and it carries no <code>kid</code> and no <code>materialVersion</code>, because the key is not a platform key. One supplied key verifies one signature, so a detached JWS signed by several keys is refused with 422 and <code>extensions.errorCode</code> <code>JWS_SINGLE_SIGNATURE_REQUIRED</code> before any signature is verified: verifying it needs a key per signer. A JWS signed by several platform keys is verified by <code>POST /api/v3/crypto/stream/verify</code>.  <strong>Accepted <code>alg</code> values.</strong> The JWS was signed by a third party, so the protected <code>alg</code> is honoured (RFC 7515 §4.1.1): it selects the verification scheme and must be a registered JWS algorithm that fits the supplied key. • RSA key: <code>RS256</code>, <code>RS384</code>, <code>RS512</code>   (RSASSA-PKCS1-v1_5) and <code>PS256</code>, <code>PS384</code>, <code>PS512</code>   (RSASSA-PSS, MGF1 over the same hash, salt of the hash length; RFC 7518 §3.3, §3.5). • EC key: the one ECDSA <code>alg</code> of its curve, with the fixed-length   <code>r||s</code> signature of RFC 7518 §3.4 — <code>ES256</code> (P-256),   <code>ES384</code> (P-384), <code>ES512</code> (P-521), and <code>ESB256</code>,   <code>ESB384</code>, <code>ESB512</code> on brainpoolP256r1, brainpoolP384r1 and   brainpoolP512r1 (the fully-specified brainpool ECDSA names RFC 9864 registers for   COSE; JOSE defines no brainpool identifier). • Ed25519 or Ed448 key: <code>EdDSA</code> (RFC 8037) or the curve's fully-specified   name, <code>Ed25519</code> or <code>Ed448</code> (RFC 9864). • ML-DSA and the other post-quantum signing keys: the parameter-set name, e.g.   <code>ML-DSA-65</code>.  Refused with 422 before any verification: <code>none</code>, an absent <code>alg</code>, an HMAC <code>alg</code> such as <code>HS256</code>, a composite <code>alg</code> (a composite signature is not a single-key signature), and an <code>alg</code> that does not fit the key, such as <code>ES256</code> on a P-384 key. ",
                 "item": [
                            {
                                "name": "Verify a detached flattened-JSON JWS with a supplied public key (stream).",
                                "request": {
    "method": "POST",
    "header": [
        {
        "key": "Content-Type",
        "value": "multipart/form-data",
        "description": "",
        "disabled": false
        },
        {
        "key": "Accept",
        "value": "application/problem+json",
        "description": "",
        "disabled": false
        }
    ],
    "body": {
    "mode": "raw",
    "raw": "",
    "options": {
    "raw": {
    "language": "json"
    }
    }
    },
    "url": {
    "raw": "{{baseUrl}}/api/v3/interoperability/verify",
    "host": [
    "{{baseUrl}}"
    ],
    "path": [
        "api",
        "v3",
        "interoperability",
        "verify"
    ],
    "variable": [
    ],
    "query": [
    ]
    },
    "description": "Accepts two multipart parts: • <code>metadata</code> – JSON (<em>SignatureUtilityApi</em>)   containing the caller's detached-JWS object (<code>signatureBase64</code>)   <strong>and</strong> the corresponding <code>publicKey</code>. • <code>file</code> – the raw payload that was signed.  The controller ignores any <code>kid</code> inside the JWS header and uses the public key supplied by the caller for streaming verification. It answers 200 with a <em>VerifySignatureResponse</em> carrying <code>valid</code> (<code>true</code> or <code>false</code>) and one <code>signatureResults</code> entry for the one signature the supplied key verifies: its <code>algorithm</code> is the one the caller declared, and it carries no <code>kid</code> and no <code>materialVersion</code>, because the key is not a platform key. One supplied key verifies one signature, so a detached JWS signed by several keys is refused with 422 and <code>extensions.errorCode</code> <code>JWS_SINGLE_SIGNATURE_REQUIRED</code> before any signature is verified: verifying it needs a key per signer. A JWS signed by several platform keys is verified by <code>POST /api/v3/crypto/stream/verify</code>.  <strong>Accepted <code>alg</code> values.</strong> The JWS was signed by a third party, so the protected <code>alg</code> is honoured (RFC 7515 §4.1.1): it selects the verification scheme and must be a registered JWS algorithm that fits the supplied key. • RSA key: <code>RS256</code>, <code>RS384</code>, <code>RS512</code>   (RSASSA-PKCS1-v1_5) and <code>PS256</code>, <code>PS384</code>, <code>PS512</code>   (RSASSA-PSS, MGF1 over the same hash, salt of the hash length; RFC 7518 §3.3, §3.5). • EC key: the one ECDSA <code>alg</code> of its curve, with the fixed-length   <code>r||s</code> signature of RFC 7518 §3.4 — <code>ES256</code> (P-256),   <code>ES384</code> (P-384), <code>ES512</code> (P-521), and <code>ESB256</code>,   <code>ESB384</code>, <code>ESB512</code> on brainpoolP256r1, brainpoolP384r1 and   brainpoolP512r1 (the fully-specified brainpool ECDSA names RFC 9864 registers for   COSE; JOSE defines no brainpool identifier). • Ed25519 or Ed448 key: <code>EdDSA</code> (RFC 8037) or the curve's fully-specified   name, <code>Ed25519</code> or <code>Ed448</code> (RFC 9864). • ML-DSA and the other post-quantum signing keys: the parameter-set name, e.g.   <code>ML-DSA-65</code>.  Refused with 422 before any verification: <code>none</code>, an absent <code>alg</code>, an HMAC <code>alg</code> such as <code>HS256</code>, a composite <code>alg</code> (a composite signature is not a single-key signature), and an <code>alg</code> that does not fit the key, such as <code>ES256</code> on a P-384 key. "
}
                                ,"response": [
                            ]
                            }
                            ]
                        }
	                    ]
	        }
    ],
    
	"variable": [
		{
			"key": "baseUrl",
			"value": "https://{host}:{port}",
			"type": "string"
        },
		{
			"key": "port",
			"value": "443",
			"type": "string"
		},
		{
			"key": "host",
			"value": "demo.ankatech.co",
			"type": "string"
		}
	]
}

