AnkaSecure Crypto CLI — Commands Reference
CLI Version: 3.4.0 Binary:
AnkaSecureCLI(fat JAR:ankasecure-cli-crypto-3.4.0-fat.jar) Total commands: 28
This document is the complete subcommand reference for the AnkaSecure Crypto CLI. Administrative key write/lifecycle operations (generate, import, patch, rotate, revoke, archive, delete, export) are not part of this CLI; for those see the Key Management CLI Commands Reference.
Command Examples
Examples below omit the leading AnkaSecureCLI for brevity. In real usage, prepend it. Both invocation styles are supported:
Overview
28 commands grouped into five sections:
| Group | Count | Commands |
|---|---|---|
| Getting started | 2 | init, view-session |
| Keys, algorithms and limits (read-only) | 4 | list-keys, get-key-metadata, get-supported-algorithms, get-crypto-limits |
| Crypto operations (compact; four choose streaming on their own) | 8 | encrypt-file, decrypt-file, sign-file, verify-signature, sign-encrypt-file, decrypt-verify-file, reencrypt-file, resign-file |
| Streaming (explicit) | 10 | encrypt-file-stream, decrypt-file-stream, sign-file-stream, verify-signature-stream, sign-encrypt-file-stream, decrypt-verify-file-stream, reencrypt-file-stream, resign-file-stream, encrypt-file-publickey-stream, verify-signature-publickey-stream |
| PKCS#7/CMS migration | 4 | analyze-pkcs7, convert-pkcs7, analyze-pkcs7-stream, convert-pkcs7-stream |
Operation modes:
- Compact (in-memory): Base64-encoded JSON payload — default for small files.
- Auto-streaming: Four of the eight commands under "Crypto operations" choose streaming on their own.
encrypt-fileandsign-fileswitch when the input reaches the server's configured compact limit (crypto.max-plaintext-bytes, default 4 MB, discovered viaGET /api/v3/crypto/limits), and a413on their compact call triggers a transparent streaming retry.decrypt-fileandreencrypt-filechoose by the input's format: a streaming artifact is processed over the streaming route.verify-signature,sign-encrypt-file,decrypt-verify-fileandresign-filealways use the compact endpoint. - Under PQC transport (
pqc.transport.enabled=true), the commands that pick streaming by file size,encrypt-fileandsign-file, do not switch automatically: the streaming routes travel under TLS only, so streaming is an explicit choice. A file at or above the compact limit, or a compact upload refused as too large in a response the PQC session did not encrypt, ends the command with exit code3and a message naming the command to run instead with the same arguments (encrypt-file-stream,sign-file-stream).decrypt-fileandreencrypt-fileof a streaming artifact use the TLS-only streaming route, as at encryption time. See Excluded Endpoints. - Explicit streaming: The ten
*-streamcommands always stream, regardless of input size. - Interactive boxed menu:
AnkaSecureCLI --interactive(see Interactive Mode Guide).
Global flags
These flags work on every subcommand:
| Flag | Effect |
|---|---|
--config-path <file> | Override the default config file location |
-h, --help | Show help for the command |
-V, --version | Print CLI version and exit |
The configuration file location is resolved in this order: --config-path <file> → the cli.config JVM system property (-Dcli.config=<file>) → ~/.ankasecure-crypto/config.properties. There is no environment-variable equivalent.
Environment variables:
LANG,LC_ALL— used to select the locale (English / Spanish).
1. Getting started
init
Initialize the CLI with server credentials and store them encrypted at ~/.ankasecure-crypto/config.properties.
Interactive prompt mode (default):
The CLI prompts for: server URL, TLS verification, Client ID, and Client Secret (echo off).
Non-interactive (silent) mode:
--client-secret takes no value on the command line. Invoke the flag bare to be prompted with echo off; --client-secret <value> fails to parse, because an inline secret is world-readable in the OS process listing and durable in the shell history. When invoking init by command, supply the secret in the environment under ANKASECURE_CLIENT_SECRET:
# Type the secret at the silent read; a value written into an export line stays in the shell history.
read -rs ANKASECURE_CLIENT_SECRET
export ANKASECURE_CLIENT_SECRET
init \
--silent \
--url https://ankasecure.example.com \
--client-id 7f3c1a90-2b64-4d1e-9c05-8ab6f2e41d77
The secret stays readable in the CLI's process environment, and in the operating system's copy of it (/proc/<pid>/environ on Linux), for the life of the process; no process can remove it. The CLI warns on standard error, naming the variable, whenever a secret arrives this way. For interactive use, run init with --client-secret and answer the prompt instead. For --silent and CI the variable is the only input, and the secret stays exposed this way. ANKASECURE_CLIENT_ID supplies the actor the same way, so a pipeline may pass neither credential half as a flag.
| Flag | Required? | Description |
|---|---|---|
--url <url> | Unless already recorded | Address of the ANKASecure deployment (https://ankasecure.example.com or ankasecure.example.com:443). Falls back to ANKASECURE_CRYPTO_SERVER_URL, then to the address the configuration already names. There is no default: an init that names no deployment is refused |
--client-id <id> | Yes, on every path | The actor UUID issued by the tenant administrator; checked to be a UUID before anything is written. Falls back to ANKASECURE_CLIENT_ID, then to a prompt |
--client-secret | Yes, on the native path | Takes no value. Bare, it prompts with echo off. For --silent / CI set ANKASECURE_CLIENT_SECRET instead |
--silent | No | Skip every prompt; each value must then come from a flag or an environment variable |
--insecure | No | Skip TLS certificate verification (self-signed certs, development only). Also readable from ANKASECURE_CRYPTO_SKIP_TLS_VERIFY |
--force | No | Overwrite existing credentials, even if the CLI is already initialised |
The six flags above declare the native credential — a client secret this deployment issued. init accepts eight more that declare an external identity instead (--external-issuer, --external-client-id, --external-client-secret, --external-audience, --external-scope, --external-token-file, --external-token-command, --external-token-command-timeout-ms) plus --actor-key-file and --expected-audience for a registered key pair. One invocation declares ONE credential; naming two is refused before anything reaches disk. See Workload Identity Federation — the Crypto CLI*.
The credentials are encrypted with AES-256-GCM using a PBKDF2-derived key (PBKDF2WithHmacSHA256, 150 000 iterations) and a 32-byte random salt. The JWT obtained at runtime is held in memory only and never written to disk.
view-session
Display the current session: server URL, authentication mode, JWT subject/issuer/expiry. There is no tenant option: the platform takes the tenant from the authenticated actor.
No required flags. Useful for verifying that init succeeded and that the JWT is still valid.
2. Key browsing (read-only)
list-keys
List keys visible to the authenticated client. By default the command auto-paginates and returns ALL matching keys (pages are fetched from the server one by one until the inventory is exhausted). All filters are applied server-side before pagination, so totals always reflect the filtered count.
list-keys [--origin <origin>] [--restricted <bool>] [--kty <kty>] [--status <status>] [--limit N] [--format <fmt>]
| Flag | Description |
|---|---|
--origin | Filter by key origin — the two published origins: GENERATED, IMPORTED. The accepted set, the --help text and the completion candidates are all derived from the SDK's KeyOrigin enum, so they cannot drift from the wire |
--restricted | Filter by restriction status: true (restricted only), false (unrestricted only) |
--kty | Filter by key type. Takes a published key-type token — the same value the kty column shows: 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, or COMPOSITE for every hybrid pairing. A composite mode name is not a key type and is rejected |
--status | Filter by lifecycle status. Takes a published key-status token — the same value the status column shows: active, pending_rotation, rotated, expired, revoked, archived, deleted_logical, suspended, pending_destruction. Matching is case-insensitive on the client; any other value is rejected before the request is sent. |
--limit | Stop fetching once N keys are collected (must be >= 1). When more keys match, the output is prefixed with Showing first N of M keys. Without --limit, ALL matching keys are returned |
--format | Output format: table (default), detailed, json. The accepted set, the help text and the renderer are one closed vocabulary — an unrecognised value is a usage error, never a silent fallback |
get-key-metadata
Retrieve the full metadata of one key.
| Flag | Required? | Description |
|---|---|---|
--kid | Yes | Key identifier |
The metadata is printed as JSON; the command takes no output-format flag.
get-supported-algorithms
Query the platform for algorithms enabled by the tenant policy.
get-supported-algorithms [--kty <types>] [--alg <algs>] [--category <cat>] [--status <st>]
[--composite-mode <modes>] [--key-ops <ops>] [--security-level <n>]
[--min-security-level <n>] [--max-security-level <n>] [--standards <std>]
[--format <fmt>] [--count]
| Flag | Description |
|---|---|
--kty | Comma-separated key type(s): ML-KEM, ML-DSA, SLH-DSA, FALCON, RSA, EC, oct, OKP, … or COMPOSITE for every hybrid pairing |
--alg | Comma-separated algorithm(s): ML-KEM-768, RSA-4096, AES-GCM-256, … |
--category | CLASSICAL, POST_QUANTUM, HYBRID — all three, derived from the SDK's AlgorithmInfo.Category |
--status | RECOMMENDED, LEGACY, EXPERIMENTAL — all three, derived from the SDK's AlgorithmInfo.Status |
--composite-mode | Comma-separated composite construction(s): COMPOSITE_KEM_COMBINE, COMPOSITE_SIGNATURE. This is the axis hybrid entries are distinguished on — every one of them publishes kty = COMPOSITE, so --kty does not separate them |
--key-ops | Required operations (AND): encrypt, decrypt, sign, verify |
--security-level | Exact NIST security level: 1, 3, 5 |
--min-security-level / --max-security-level | Inclusive NIST security-level bounds |
--standards | Required standards (AND): NIST, BSI, ANSSI, ENISA, ISO, … |
--format | Output format: table (default), detailed, json |
--count | Print only the number of matching algorithms |
Filter logic: --key-ops and --standards are AND (an algorithm must support all listed values); --kty, --alg and --composite-mode are OR (any listed value matches).
get-crypto-limits
Print the largest plaintext a compact (non-streaming) operation accepts for the caller's tenant, and where the value came from.
| Source | Meaning | Exit code |
|---|---|---|
SERVER | Read from GET /api/v3/crypto/limits: the tenant's effective limit | 0 |
DEFAULT_AFTER_FAILURE | The server could not be read; the SDK's default (4,000,000 bytes) is printed, with a warning on stderr | 3 |
A script therefore never takes the SDK's default for the server's limit. The automatic compact/streaming choice of the crypto commands uses this same value.
3. Crypto operations (small files)
Flags of the eight commands (each command accepts only the flags its row names):
| Flag | Accepted by | Description |
|---|---|---|
--kid | encrypt-file, sign-file | Key identifier |
--sign-kid, --encrypt-kid | sign-encrypt-file | Signing key and encryption key |
--new-kid | reencrypt-file, resign-file | Target key; the source key is read from the envelope or signature |
--recipient-kid | decrypt-file, decrypt-verify-file, and their streaming counterparts decrypt-file-stream, decrypt-verify-file-stream | The recipient that decrypts. Required when the JWE is addressed to several keys; optional for a JWE that names one key (when given it must equal that key) |
--source-kid | reencrypt-file, resign-file, and their streaming counterparts reencrypt-file-stream, resign-file-stream | The recipient or signature the operation replaces. Required when the token is addressed to or signed by several keys (every other recipient or signature is kept); for a JWE it also names the source key when the header names none; optional for a token of one key |
--input-file | every command except verify-signature and resign-file | Source file |
--output-file | encrypt-file, decrypt-file, sign-encrypt-file, decrypt-verify-file, reencrypt-file | Destination file |
--output-signature-file | sign-file | Signature destination |
--input-signature-file | verify-signature | Signature to verify |
--old-signature-file, --new-signature-file | resign-file | Signature to re-sign, and its destination |
--serialization | sign-file, sign-encrypt-file, resign-file | JWS serialization: compact or json |
--force | every command except verify-signature | Overwrite an existing output file |
--quiet | encrypt-file, sign-file, verify-signature, sign-encrypt-file, decrypt-verify-file, resign-file | Suppress informational messages |
--force-compact | encrypt-file, sign-file | Force compact mode even for large files (may produce HTTP 413) |
encrypt-file
decrypt-file
The key id is recovered from the envelope; --kid is not required. A JWE addressed to several keys (the output of a multi-recipient PKCS#7 conversion) is decrypted with the recipient --recipient-kid names; the server never tries another recipient:
decrypt-file --recipient-kid custodian-b --input-file board-minutes.jwe --output-file board-minutes.pdf
sign-file
sign-file --kid signing-key --input-file contract.pdf --output-signature-file contract.sig
sign-file --kid signing-key --input-file contract.pdf --output-signature-file contract.sig --validity-days 365
--validity-days <days> sets the signature's validity. It is refused at parse time outside the range the SDK declares (1 to 3650 days), and the server refuses a value above the deployment's maximum. Given, it pins the compact endpoint like --serialization, so a file above the compact limit fails with 413 instead of switching to streaming.
verify-signature
Returns exit code 0 if the signature is valid, non-zero otherwise. A JWS signed by several keys is valid only when every signature verifies. The command prints one line per signer, in token order:
Signers:
Signer 1: acme-treasury-signer (algorithm ML-DSA-65, material version 2) - VALID
Signer 2: acme-legal-signer (algorithm RSA-3072, material version 1) - VALID
decrypt-verify-file, verify-signature-stream, decrypt-verify-file-stream and verify-signature-publickey-stream print the same lines; a kid or material version the server did not report (the public-key verify is given its key by the caller) prints as not reported.
sign-encrypt-file
Sign-then-encrypt in a single call (uses two keys: one for signing, one for encryption).
sign-encrypt-file \
--sign-kid sign-key \
--encrypt-kid enc-key \
--input-file payroll.csv \
--output-file payroll.bin \
--validity-days 90
--validity-days <days> sets the inner signature's validity (1 to 3650 days).
decrypt-verify-file
For an outer JWE addressed to several keys, name the recipient that decrypts with --recipient-kid; it must be none of the inner signers.
reencrypt-file
Decrypt with the original key and re-encrypt with a new key (algorithm rotation) without exposing plaintext to disk.
For a JWE addressed to several keys, --source-kid names the ONE recipient replaced; every other recipient is kept, under a fresh content-encryption key. The command prints every recipient of the produced JWE:
reencrypt-file --new-kid archive-2026 --source-kid custodian-a --input-file board-minutes.jwe --output-file board-minutes-2026.jwe
Recipients of the re-encrypted JWE:
Recipient 1: archive-2026 (algorithm ML-KEM-768, material version 1)
Recipient 2: custodian-b (algorithm RSA-3072, material version 3)
Recipient 3: custodian-c (algorithm ML-KEM-1024, material version 2)
resign-file
Re-sign an existing signed file with a different signing key.
resign-file --new-kid new-mldsa-key --old-signature-file contract.sig --new-signature-file contract-v2.sig
For a JWS signed by several keys, --source-kid names the ONE signature replaced. Every signature is verified first — one that does not verify refuses the command with a non-zero exit and nothing is written — and the command prints the signers of the input JWS.
4. Streaming operations (explicit)
The ten *-stream commands always stream, regardless of input size. They take the key and file flags of their non-streaming counterparts (--kid, --sign-kid/--encrypt-kid, --new-kid, --input-file, --output-file, the signature-file flags, --force where there is an output file). They take no --quiet, --serialization or --force-compact, and no buffer-size or progress flag. decrypt-file-stream and decrypt-verify-file-stream add --recipient-kid <kid>, and reencrypt-file-stream and resign-file-stream add --source-kid <kid>, with the meanings the table in section 3 gives.
encrypt-file-stream / decrypt-file-stream
encrypt-file-stream --kid ml-kem-key --input-file backup.tar --output-file backup.tar.enc
decrypt-file-stream --input-file backup.tar.enc --output-file backup.tar
sign-file-stream / verify-signature-stream
sign-file-stream --kid sign-key --input-file big.iso --output-signature-file big.iso.sig
verify-signature-stream --input-file big.iso --input-signature-file big.iso.sig
sign-encrypt-file-stream
sign-encrypt-file-stream \
--sign-kid sign-key \
--encrypt-kid enc-key \
--input-file dataset.tar \
--output-file dataset.bin \
--validity-days 90 \
--flavor COMPOSITE
--validity-days <days> sets the inner signature's validity. --flavor is an advisory key-flavor hint (SYMMETRIC, ASYMMETRIC, COMPOSITE); the server derives the effective flavor from the keys, and the hint does not change which keys are used.
reencrypt-file-stream / resign-file-stream
reencrypt-file-stream --new-kid ml-kem-key --input-file legacy.bin --output-file pqc.bin
resign-file-stream --new-kid new-mldsa-key --old-signature-file big.iso.sig --input-file big.iso --new-signature-file big.iso-v2.sig --validity-days 365
resign-file-stream takes --validity-days <days> for the new signature.
encrypt-file-publickey-stream
Streaming encryption with an externally-supplied public key (instead of a key id stored on the platform).
encrypt-file-publickey-stream \
--kty ML-KEM --alg ML-KEM-768 --public-key recipient-pubkey.json \
--input-file data.csv \
--output-file data.bin
verify-signature-publickey-stream
verify-signature-publickey-stream \
--kty ML-DSA --alg ML-DSA-65 --public-key signer-pubkey.json \
--input-file document.pdf \
--input-signature-file document.sig
5. PKCS#7 / CMS migration
These commands analyse legacy PKCS#7 / CMS files and convert them to JOSE (JWS / JWE). The conversion keeps the classical keys — the content is re-signed with each signer's key and re-encrypted under A256GCM to each recipient's key — and every actor needs a tenant key imported with its private key (current limitation: a certificate imported alone is refused). To move the result to a post-quantum algorithm, re-encrypt or re-sign it afterwards with reencrypt-file or resign-file.
The CLI's actor also needs a Capability Grant per key, or convert-pkcs7 and convert-pkcs7-stream are refused 403 before any key is resolved: REENCRYPT from the recipient that decrypts to every recipient (its own pair included) and RESIGN from each signer's key to itself. A REENCRYPT or RESIGN grant is requested with exactly two assetKids: N recipients need N-1 pair grants [decrypting recipient, recipient], a single recipient needs the in-place grant, requested with its kid twice (assetKids: [kid, kid]) and stored as [kid], and each signer needs RESIGN [signer, signer]. There is no wildcard REENCRYPT or RESIGN grant. DECRYPT, ENCRYPT and SIGN grants do not authorize a conversion. A tenant administrator creates the grants; this CLI does not. See the Operation → Capability Grant Matrix.
analyze-pkcs7
Inspect a PKCS#7/CMS structure: every signer and every recipient, algorithms, the JOSE form a conversion produces and every tenant key it needs. Read-only; decrypts nothing.
Analysis takes no key and no option: the command sends the file only, and analyze-pkcs7-stream likewise.
convert-pkcs7
Convert a PKCS#7/CMS file (up to the migration upload limit, default 5 MB) to JOSE. Every signer and every recipient is carried.
| Flag | Required? | Description |
|---|---|---|
--input-file | Yes | Input PKCS#7/CMS file |
--output-file | Yes | Destination; the JOSE token is written exactly as the server returned it (UTF-8) — a General JSON token is not re-serialized |
--decrypt-kid | No | For an encrypted structure, the kid of the recipient key that decrypts. When omitted, the first recipient in encoded order whose tenant key admits decryption and encryption decrypts |
--serialization | No | AUTO (default), COMPACT or JSON. AUTO: Compact for at most one signer and at most one recipient, General JSON otherwise. COMPACT for a file with several signers or recipients is refused 422 INCOMPATIBLE_SERIALIZATION. Any other value is refused by the CLI before a request is sent |
--target-format | No | AUTO (default), JWS, JWE or JWE_JWS_NESTED; must match the structure |
--force | No | Overwrite the output file if it exists |
The summary printed after a conversion reports the structure, the serialization and the number of signers and recipients carried.
analyze-pkcs7-stream / convert-pkcs7-stream
Streaming variants for large files, with no API size limit. They take the same flags; for convert-pkcs7-stream, --serialization accepts the same AUTO, COMPACT and JSON, where the single-actor form is the flattened detached JWS (one signer) or the multipart JWE with a one-recipient header, and JSON is the General form.
analyze-pkcs7-stream --input-file enterprise-backup.p7m
convert-pkcs7-stream \
--input-file enterprise-backup.p7m \
--output-file enterprise-backup.jose
A result with several signatures or several recipients is opened, verified, re-signed and re-encrypted by the crypto commands: name the recipient that decrypts with --recipient-kid, and the ONE signer or recipient being rotated with --source-kid. A refusal (400, 403, 422) ends the command with a non-zero exit and leaves no partial output file.
When convert-pkcs7 or convert-pkcs7-stream is refused 403 by the Capability Grant gate (the problem detail starts Operation denied by Capability Grant resolver:), the CLI prints a hint that names the grants a conversion needs. The same gate also answers a key-lifecycle refusal, which the hint cannot tell apart, so it also reminds you that every key must be active. A 403 for a missing scope prints no hint.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Invalid or missing arguments |
| 2 | Command not recognised |
| 3 | Runtime or SDK exception |
Where did the administrative key commands go?
The Crypto CLI carries no key-generation, import, export or lifecycle command. Key management is the Key Management CLI's (ankasecure-km), run as an administrative workload of the tenant:
| Key Management CLI command | Purpose |
|---|---|
keys create, keys import-key, keys import-keystore | Create or import a key |
keys list, keys get, keys export | Browse keys; export the public part |
keys update | Change a key's metadata |
rotation rotate, rotation replace-schedule | Rotate a key now, or on a schedule |
keys suspend, keys reactivate, keys revoke, keys archive, materials revoke | Lifecycle transitions |
destruction request-key, destruction request-version | Request a destruction, which people approve in the Admin Console |
People do the same in the Admin Console. See the Key Management CLI Commands Reference and Key Destruction.
CLI Version: 3.4.0 Java Version: 25
© 2025 ANKATech Solutions Inc. All rights reserved.