Keyset Tool
The Keyset Tool is a command-line utility for generating Tink keyset configurations (JSON or YAML) used by all Kryptonite for Kafka modules. It supports both plain and encrypted keyset generation for the supported cipher key types and cloud KMS integrations.
Getting the Tool
Direct download
Download the pre-built fat JAR from the GitHub Releases page. From the attached assets choose kryptonite-keyset-tool-<VERSION>.jar which is a self-contained, runnable JAR.
Build from sources
The JAR is produced at kryptonite-keyset-tool/target/kryptonite-keyset-tool-<VERSION>.jar.
Usage
Usage: kryptonite-keyset-tool [-ehpV] [--yaml] -a=<algorithm> [-f=<outputFormat>]
[-i=<identifier>] [--initial-key-id=<initialKeyId>]
[-k=<numKeysets>] [--kek-config=<kekConfigFile>]
[--kek-type=<kekType>] [--kek-uri=<kekUri>]
[-n=<numKeys>] [-o=<outputFile>] [-s=<keySize>]
Or run directly via Maven:
Options
| Option | Required | Default | Description |
|---|---|---|---|
-a, --algorithm |
Yes | — | Cipher algorithm: AES_GCM, AES_GCM_SIV, or FPE_FF31 |
-i, --identifier |
When format=FULL |
— | Keyset identifier (required when output format is FULL) |
-f, --output-format |
No | FULL |
FULL (with identifier wrapper) or RAW (bare Tink keyset) |
-s, --key-size |
No | 256 |
Key size in bits. AES_GCM: 128 or 256. AES_GCM_SIV: fixed (ignored). FPE_FF31: 128, 192, or 256 |
-n, --num-keys |
No | 1 |
Number of keys per keyset (1–1000) — useful for key rotation setups |
-k, --num-keysets |
No | 1 |
Number of keysets to generate. When >1, output is a JSON array (or YAML sequence with --yaml); identifiers are suffixed _1, _2, etc. |
--initial-key-id |
No | 10000 |
Starting key ID, incremented by 1 per additional key |
-o, --output |
No | stdout |
Output file path (default: stdout) |
-p, --pretty |
No | false |
Pretty-print JSON output (default: single-line; ignored for YAML) |
--yaml |
No | false |
Output YAML instead of JSON |
-e, --encrypt |
No | false |
Encrypt the generated keyset(s) using a KMS key encryption key (KEK). Requires: --kek-type, --kek-uri, --kek-config |
--kek-type |
When -e or --encrypt |
— | GCP, AWS, or AZURE |
--kek-uri |
When -e or --encrypt |
— | KMS key URI (see format below) |
--kek-config |
When -e or --encrypt |
— | Path to a credentials JSON file |
-h, --help |
— | — | Show this help message and exit |
-V, --version |
— | — | Print version information and exit |
KEK URI formats
| Provider | URI format |
|---|---|
| GCP | gcp-kms://projects/<project>/locations/<location>/keyRings/<ring>/cryptoKeys/<key> |
| AWS | aws-kms://arn:aws:kms:<region>:<account>:key/<key-id> |
| Azure | azure-kv://<vault-name>.vault.azure.net/keys/<key-name> |
Key ID assignment
Key IDs are assigned sequentially from --initial-key-id. The first (lowest) key ID becomes the primaryKeyId. When generating multiple keysets (-k N), IDs are non-overlapping across keysets.
Example with -n 3 -k 2 --initial-key-id 1000:
- Keyset 1: IDs 1000, 1001, 1002 (primary = 1000)
- Keyset 2: IDs 1003, 1004, 1005 (primary = 1003)
Plain Keysets
Single AES-GCM keyset (FULL format, JSON)
Output:
{
"identifier": "my-aes-key",
"material": {
"primaryKeyId": 10000,
"key": [
{
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 10000,
"outputPrefixType": "TINK"
}
]
}
}
Single AES-GCM keyset (FULL format, YAML)
Output:
identifier: my-aes-key
material:
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
YAML output is always multi-line. The --pretty flag is ignored when --yaml is set.
Single AES-GCM-SIV keyset (RAW format, JSON)
Output:
{
"primaryKeyId" : 10000,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesSivKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10000,
"outputPrefixType" : "TINK"
} ]
}
Single AES-GCM-SIV keyset (RAW format, YAML)
Output:
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesSivKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
Use AES_GCM_SIV for deterministic encryption of Kafka record keys — determinism preserves topic partitioning.
FPE keyset 192-bit (FULL format)
Output:
{
"identifier" : "my-fpe-key",
"material" : {
"primaryKeyId" : 10000,
"key" : [ {
"keyData" : {
"typeUrl" : "io.github.hpgrahsl.kryptonite/crypto.custom.mysto.fpe.FpeKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10000,
"outputPrefixType" : "RAW"
} ]
}
}
FPE keyset output uses typeUrl: io.github.hpgrahsl.kryptonite/crypto.custom.mysto.fpe.FpeKey and outputPrefixType: RAW.
Single multi-key keyset
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i my-rotating-key -f FULL -n 3 --initial-key-id 20000 -p
Output:
{
"identifier" : "my-rotating-key",
"material" : {
"primaryKeyId" : 20000,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 20000,
"outputPrefixType" : "TINK"
}, {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 20001,
"outputPrefixType" : "TINK"
}, {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 20002,
"outputPrefixType" : "TINK"
} ]
}
}
Multiple single-key keysets (JSON array)
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i demo-key -f FULL -k 2 -n 1 --initial-key-id 10000 -p
Output:
[ {
"identifier" : "demo-key_1",
"material" : {
"primaryKeyId" : 10000,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10000,
"outputPrefixType" : "TINK"
} ]
}
}, {
"identifier" : "demo-key_2",
"material" : {
"primaryKeyId" : 10001,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10001,
"outputPrefixType" : "TINK"
} ]
}
} ]
Produces a JSON array of 2 keyset objects with identifiers demo-key_1 and demo-key_2 each containing a single key.
Multiple single-key keysets (YAML sequence)
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i demo-key -f FULL -k 2 -n 1 --initial-key-id 10000 --yaml
Output:
- identifier: demo-key_1
material:
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
- identifier: demo-key_2
material:
primaryKeyId: 10001
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10001
outputPrefixType: TINK
Produces a YAML sequence of 2 keyset objects. This format is particularly convenient for Kroxylicious filter configurations, which are natively YAML-based.
RAW keyset format
Use RAW format when uploading directly as a secret value to a cloud secret manager. Note that the identifier wrapper is not needed there — the secret name itself acts as the identifier:
Output:
{
"primaryKeyId" : 10000,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10000,
"outputPrefixType" : "TINK"
} ]
}
Writing keysets to output files
File keyset.json:
{
"primaryKeyId" : 10000,
"key" : [ {
"keyData" : {
"typeUrl" : "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value" : "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType" : "SYMMETRIC"
},
"status" : "ENABLED",
"keyId" : 10000,
"outputPrefixType" : "TINK"
} ]
}
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i my-aes-key -f FULL -o /path/to/keyset.yaml --yaml
File keyset.yaml:
identifier: my-aes-key
material:
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
Encrypted Keysets
When key_source=CONFIG_ENCRYPTED or key_source=KMS_ENCRYPTED, keysets are expected to be encrypted at rest using a key encryption key (KEK) stored in a supported cloud KMS. Pass -e together with --kek-type, --kek-uri, and --kek-config.
The --kek-config option takes a file path to a JSON credentials file — not an inline JSON string.
Encrypted keyset with GCP Cloud KMS
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i my-key -f RAW -p \
-e --kek-type GCP \
--kek-uri "gcp-kms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-kek" \
--kek-config /path/to/gcp-credentials.json
gcp-credentials.json:
{
"type": "service_account",
"project_id": "...",
"private_key_id": "...",
"private_key": "...",
"client_email": "...",
"client_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
}
Encrypted keyset with AWS KMS
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i my-key -f RAW -p \
-e --kek-type AWS \
--kek-uri "aws-kms://arn:aws:kms:eu-central-1:123456789012:key/abcd-1234-efgh-5678" \
--kek-config /path/to/aws-credentials.json
aws-credentials.json:
Encrypted keyset with Azure Key Vault
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM -i my-key -f RAW -p \
-e --kek-type AZURE \
--kek-uri "azure-kv://my-vault.vault.azure.net/keys/my-kek-key" \
--kek-config /path/to/azure-credentials.json
azure-credentials.json:
{
"clientId": "...",
"tenantId": "...",
"clientSecret": "...",
"keyVaultUrl": "https://my-vault.vault.azure.net"
}
Azure envelope encryption
Azure Key Vault standard tier only supports RSA keys — symmetric AEAD is not available. The module transparently implements envelope encryption: the keyset is encrypted locally with AES-256-GCM, and only the 32-byte DEK is wrapped with RSA-OAEP-256 via Azure Key Vault. The caller does not need to configure anything differently.
Multiple encrypted keysets
Example keyset tool call with GCP KMS keyset encryption intended for key_source=CONFIG_ENCRYPTED uses which expects FULL keyset format.
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM_SIV -i det-key -f FULL -k 3 -n 2 -p \
-e --kek-type GCP \
--kek-uri "gcp-kms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-kek" \
--kek-config /path/to/gcp-credentials.json \
-o encrypted-keysets-full.json
Example keyset tool call with GCP KMS keyset encryption intended for key_source=KMS_ENCRYPTED uses which expects RAW keyset format.
java -jar kryptonite-keyset-tool-0.2.0-SNAPSHOT.jar \
-a AES_GCM_SIV -f RAW -k 3 -n 2 -p \
-e --kek-type GCP \
--kek-uri "gcp-kms://projects/my-project/locations/global/keyRings/my-ring/cryptoKeys/my-kek" \
--kek-config /path/to/gcp-credentials.json \
-o encrypted-keysets-raw.json
Output structures by format and encryption mode
--output-format |
--yaml |
-e |
Resulting structure |
|---|---|---|---|
FULL |
No | No | JSON object with identifier and material containing plain Tink keyset (details) |
FULL |
No | Yes | JSON object with identifier and material containing encrypted Tink keyset (details) |
FULL |
Yes | No | YAML mapping with identifier and material containing plain Tink keyset (details) |
FULL |
Yes | Yes | YAML mapping with identifier and material containing encrypted Tink keyset (details) |
RAW |
No | No | JSON object with plain Tink keyset fields (details) |
RAW |
No | Yes | JSON object with encrypted Tink keyset fields (details) |
RAW |
Yes | No | YAML mapping of plain Tink keyset fields (details) |
RAW |
Yes | Yes | YAML mapping of encrypted Tink keyset fields (details) |
FULL format, plain
JSON (-f FULL -p):
{
"identifier": "my-key",
"material": {
"primaryKeyId": 10000,
"key": [ {
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 10000,
"outputPrefixType": "TINK"
} ]
}
}
YAML (-f FULL --yaml):
identifier: my-key
material:
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
FULL format, encrypted
JSON (-f FULL -e -p):
{
"identifier": "my-key",
"material": {
"encryptedKeyset": "<BASE64_ENCODED_ENCRYPTED_KEYSET>",
"keysetInfo": {
"primaryKeyId": 10000,
"keyInfo": [ {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"status": "ENABLED",
"keyId": 10000,
"outputPrefixType": "TINK"
} ]
}
}
}
YAML (-f FULL -e --yaml):
identifier: my-key
material:
encryptedKeyset: "<BASE64_ENCODED_ENCRYPTED_KEYSET>"
keysetInfo:
primaryKeyId: 10000
keyInfo:
- typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
status: ENABLED
keyId: 10000
outputPrefixType: TINK
RAW format, plain
JSON (-f RAW -p):
{
"primaryKeyId": 10000,
"key": [ {
"keyData": {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"value": "<BASE64_ENCODED_KEY_HERE>",
"keyMaterialType": "SYMMETRIC"
},
"status": "ENABLED",
"keyId": 10000,
"outputPrefixType": "TINK"
} ]
}
YAML (-f RAW --yaml):
primaryKeyId: 10000
key:
- keyData:
typeUrl: type.googleapis.com/google.crypto.tink.AesGcmKey
value: "<BASE64_ENCODED_KEY_HERE>"
keyMaterialType: SYMMETRIC
status: ENABLED
keyId: 10000
outputPrefixType: TINK
RAW format, encrypted
JSON (-f RAW -e -p):
{
"encryptedKeyset": "<BASE64_ENCODED_ENCRYPTED_KEYSET>",
"keysetInfo": {
"primaryKeyId": 10000,
"keyInfo": [ {
"typeUrl": "type.googleapis.com/google.crypto.tink.AesGcmKey",
"status": "ENABLED",
"keyId": 10000,
"outputPrefixType": "TINK"
} ]
}
}
YAML (-f RAW -e --yaml):