> For the complete documentation index, see [llms.txt](https://vectis.liesware.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://vectis.liesware.com/symmetric-encryption.md).

# Symmetric Encryption

## Encrypt local data with a symmetric key

> Requires symmetric permission for the path KID and an active key. Envelope, AAD and crypto are unchanged.

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Symmetric Encryption"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"parameters":{"Kid":{"name":"kid","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Kid"}}},"schemas":{"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"InternalEncryptMessageInput":{"type":"object","required":["plaintext"],"properties":{"plaintext":{"$ref":"#/components/schemas/TextField","description":"Maximum 1,047,552 bytes when encoded as UTF-8."}}},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"InternalMessageOutput":{"type":"object","required":["timestamp","kid","message"],"properties":{"timestamp":{"$ref":"#/components/schemas/Timestamp"},"kid":{"$ref":"#/components/schemas/Kid"},"subject":{"$ref":"#/components/schemas/Subject","description":"Present only for subject-bound symmetric envelopes; never nullable."},"message":{"$ref":"#/components/schemas/InternalMessageCipher"}}},"Timestamp":{"type":"string","pattern":"^[0-9]+$"},"Subject":{"type":"string","minLength":64,"maxLength":64,"pattern":"^[0-9a-f]{64}$","description":"Profile-scoped HMAC identifier returned by subject creation. Not a user authorization credential."},"InternalMessageCipher":{"type":"object","required":["ctx","nonce","aad","variant"],"properties":{"ctx":{"$ref":"#/components/schemas/HexString"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"variant":{"$ref":"#/components/schemas/SymmetricAlgorithm"}}},"HexString":{"type":"string","pattern":"^[0-9a-fA-F]+$"},"SymmetricAlgorithm":{"enum":["ChaCha20Poly1305","AES-128/GCM","AES-192/GCM","AES-256/GCM"]},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/symmetric/encrypt/{kid}":{"post":{"tags":["Symmetric Encryption"],"summary":"Encrypt local data with a symmetric key","description":"Requires symmetric permission for the path KID and an active key. Envelope, AAD and crypto are unchanged.","parameters":[{"$ref":"#/components/parameters/Kid"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalEncryptMessageInput"}}}},"responses":{"200":{"description":"Symmetric-key envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalMessageOutput"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}}}
```

## Encrypt local data with an existing subject seed

> Requires symmetric permission and an active KID. Uses the KID algorithm and a separately derived subject key. The signed stored tokenization profile that created the seed must remain available. No token permission or ciphertext storage is required.

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Symmetric Encryption"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"parameters":{"Kid":{"name":"kid","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Kid"}},"Subject":{"name":"subject","in":"path","required":true,"schema":{"$ref":"#/components/schemas/Subject"}}},"schemas":{"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"Subject":{"type":"string","minLength":64,"maxLength":64,"pattern":"^[0-9a-f]{64}$","description":"Profile-scoped HMAC identifier returned by subject creation. Not a user authorization credential."},"InternalEncryptMessageInput":{"type":"object","required":["plaintext"],"properties":{"plaintext":{"$ref":"#/components/schemas/TextField","description":"Maximum 1,047,552 bytes when encoded as UTF-8."}}},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"SubjectSymmetricEnvelope":{"allOf":[{"$ref":"#/components/schemas/InternalMessageOutput"},{"type":"object","required":["subject"]}]},"InternalMessageOutput":{"type":"object","required":["timestamp","kid","message"],"properties":{"timestamp":{"$ref":"#/components/schemas/Timestamp"},"kid":{"$ref":"#/components/schemas/Kid"},"subject":{"$ref":"#/components/schemas/Subject","description":"Present only for subject-bound symmetric envelopes; never nullable."},"message":{"$ref":"#/components/schemas/InternalMessageCipher"}}},"Timestamp":{"type":"string","pattern":"^[0-9]+$"},"InternalMessageCipher":{"type":"object","required":["ctx","nonce","aad","variant"],"properties":{"ctx":{"$ref":"#/components/schemas/HexString"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"variant":{"$ref":"#/components/schemas/SymmetricAlgorithm"}}},"HexString":{"type":"string","pattern":"^[0-9a-fA-F]+$"},"SymmetricAlgorithm":{"enum":["ChaCha20Poly1305","AES-128/GCM","AES-192/GCM","AES-256/GCM"]},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/symmetric/encrypt/{kid}/subject/{subject}":{"post":{"tags":["Symmetric Encryption"],"summary":"Encrypt local data with an existing subject seed","description":"Requires symmetric permission and an active KID. Uses the KID algorithm and a separately derived subject key. The signed stored tokenization profile that created the seed must remain available. No token permission or ciphertext storage is required.","parameters":[{"$ref":"#/components/parameters/Kid"},{"$ref":"#/components/parameters/Subject"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalEncryptMessageInput"}}}},"responses":{"200":{"description":"Complete subject-bound symmetric envelope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectSymmetricEnvelope"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}}}
```

## Decrypt a symmetric-key envelope

> Requires symmetric permission for the envelope KID and an active or retired key. A non-null subject selects subject-bound decryption with no fallback; absence selects legacy. The AAD purpose must match and is authenticated. Missing subjects return 404; corrupt seeds or missing creator configuration produce sanitized internal errors.

```json
{"openapi":"3.1.0","info":{"title":"Vectis HTTP API","version":"v1"},"tags":[{"name":"Symmetric Encryption"}],"servers":[{"url":"http://127.0.0.1:3000","description":"Local default server over HTTP"},{"url":"https://127.0.0.1:3000","description":"Local HTTPS server when VECTIS_MODE=prod"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"InternalMessageOutput":{"type":"object","required":["timestamp","kid","message"],"properties":{"timestamp":{"$ref":"#/components/schemas/Timestamp"},"kid":{"$ref":"#/components/schemas/Kid"},"subject":{"$ref":"#/components/schemas/Subject","description":"Present only for subject-bound symmetric envelopes; never nullable."},"message":{"$ref":"#/components/schemas/InternalMessageCipher"}}},"Timestamp":{"type":"string","pattern":"^[0-9]+$"},"Kid":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"},"Subject":{"type":"string","minLength":64,"maxLength":64,"pattern":"^[0-9a-f]{64}$","description":"Profile-scoped HMAC identifier returned by subject creation. Not a user authorization credential."},"InternalMessageCipher":{"type":"object","required":["ctx","nonce","aad","variant"],"properties":{"ctx":{"$ref":"#/components/schemas/HexString"},"nonce":{"$ref":"#/components/schemas/HexString"},"aad":{"$ref":"#/components/schemas/TextField"},"variant":{"$ref":"#/components/schemas/SymmetricAlgorithm"}}},"HexString":{"type":"string","pattern":"^[0-9a-fA-F]+$"},"TextField":{"type":"string","minLength":1,"pattern":"^[^\\x00-\\x1F\\x7F-\\x9F]+$"},"SymmetricAlgorithm":{"enum":["ChaCha20Poly1305","AES-128/GCM","AES-192/GCM","AES-256/GCM"]},"DecryptMessageOutput":{"type":"object","required":["plaintext"],"properties":{"plaintext":{"$ref":"#/components/schemas/TextField"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"$ref":"#/components/schemas/TextField"}}}},"responses":{"RequestBodyTooLarge":{"description":"Request body exceeds the internal 2 MiB limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Error":{"description":"Public error response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/symmetric/decrypt":{"post":{"tags":["Symmetric Encryption"],"description":"Requires symmetric permission for the envelope KID and an active or retired key. A non-null subject selects subject-bound decryption with no fallback; absence selects legacy. The AAD purpose must match and is authenticated. Missing subjects return 404; corrupt seeds or missing creator configuration produce sanitized internal errors.","summary":"Decrypt a symmetric-key envelope","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InternalMessageOutput"}}}},"responses":{"200":{"description":"Decrypted plaintext","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecryptMessageOutput"}}}},"413":{"$ref":"#/components/responses/RequestBodyTooLarge"},"default":{"$ref":"#/components/responses/Error"}}}}}}
```
