Skip to content

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:

AnkaSecureCLI list-keys
java -jar ankasecure-cli-crypto-3.4.0-fat.jar list-keys

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-file and sign-file switch when the input reaches the server's configured compact limit (crypto.max-plaintext-bytes, default 4 MB, discovered via GET /api/v3/crypto/limits), and a 413 on their compact call triggers a transparent streaming retry. decrypt-file and reencrypt-file choose by the input's format: a streaming artifact is processed over the streaming route. verify-signature, sign-encrypt-file, decrypt-verify-file and resign-file always use the compact endpoint.
  • Under PQC transport (pqc.transport.enabled=true), the commands that pick streaming by file size, encrypt-file and sign-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 code 3 and a message naming the command to run instead with the same arguments (encrypt-file-stream, sign-file-stream). decrypt-file and reencrypt-file of a streaming artifact use the TLS-only streaming route, as at encryption time. See Excluded Endpoints.
  • Explicit streaming: The ten *-stream commands 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):

init

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.

view-session

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.

get-key-metadata --kid <KEY_ID>
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.

get-crypto-limits [--format table|detailed|json]
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

encrypt-file --kid <KEY_ID> --input-file plaintext.txt --output-file ciphertext.bin

decrypt-file

decrypt-file --input-file ciphertext.bin --output-file plaintext.txt

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

verify-signature --input-signature-file contract.sig

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

decrypt-verify-file --input-file payroll.bin --output-file payroll.csv

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.

reencrypt-file --new-kid ml-kem-key --input-file legacy.bin --output-file pqc.bin

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.

analyze-pkcs7 --input-file legacy-signed.p7s [--output-file analysis.json] [--force]

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.

convert-pkcs7 \
    --input-file legacy-signed.p7s \
    --output-file converted.jws \
    --serialization AUTO
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.

* restricted content — see higher-tier documentation