Run a local node, create a key, sign hello, and verify the signature. The setup uses:
- one node
monokey mode- Shamir seal provider with
1-of-1unseal shares - developer token authentication
- the
arbitraryauthority for raw signing
Keep this configuration local. It uses a fixed developer token and no TLS. For production setup, see Deployment.
What this proves
The flow checks initialization, unseal, key creation, signing, and verification:
request -> raw-signing identity -> signature -> verification
To check intent policy, replace arbitrary with a custom or protocol-specific authority after completing this flow.
Requirements
- Java 25
- a built TKeeper jar
curl
Build the jar with the explicit developer-auth feature:
./gradlew :build -Pkeeper.features=all,auth-dev -Pkeeper.platforms=all
The jar is:
build/libs/tkeeper-2.6.0.jar
Create local config
Create /tmp/tkeeper/application.conf:
auth { type = "dev" }
boot { token = "local-boot-token" }
keeper {
database { path = "/tmp/tkeeper/db" }
authority { arbitrary { enabled = true } }
providers {
selected = "shamir"
shamir {
threshold = 1
total = 1
}
}
server {
public {
host = "0.0.0.0"
port = 8080
}
internal {
host = "0.0.0.0"
port = 9090
}
}
}
Create /tmp/tkeeper/dev.conf:
keeper.dev {
token = "dev-token"
permissions = [
"tkeeper.system.init",
"tkeeper.system.unseal",
"tkeeper.system.seal",
"tkeeper.dkg.create",
"tkeeper.key.*.public",
"tkeeper.key.*.sign",
"tkeeper.key.*.verify",
"tkeeper.compliance.inventory"
]
}
The example token and bootstrap token are local credentials. Use JWT authentication and permissions scoped to the required keys for a production integration.
Run TKeeper
java \
--enable-native-access=ALL-UNNAMED \
-Dkeeper.config.location=/tmp/tkeeper \
-Dkeeper.dev.enabled=true \
-Dkeeper.dev.config.location=/tmp/tkeeper \
-Dkeeper.coordinator.enabled=true \
-jar build/libs/tkeeper-2.6.0.jar
Initialize the node
curl -s \
-H 'X-DEV-TOKEN: dev-token' \
-H 'Content-Type: application/json' \
-d '{"peerId":1,"threshold":1,"total":1}' \
http://localhost:8080/v1/keeper/system/init
With the Shamir provider, the response contains shares64. Save the share outside the node. You need it to unseal TKeeper after initialization or restart.
Unseal
Replace share-from-init with one value from the shares64 response.
curl -s \
-H 'X-DEV-TOKEN: dev-token' \
-H 'Content-Type: application/json' \
-d '{"payload64":"share-from-init"}' \
http://localhost:8080/v1/keeper/system/unseal
Create a demo key identity
This creates a local SECP256K1 identity that can authorize arbitrary signing requests.
curl -s \
-H 'X-DEV-TOKEN: dev-token' \
-H 'Content-Type: application/json' \
-d '{
"keyId": "demo-identity",
"algorithm": "SECP256K1",
"mode": "CREATE",
"authorities": [
{ "id": "arbitrary" }
]
}' \
http://localhost:8080/v2/keeper/dkg
See Authorities to create a key with intent policy.
Sign
This signs hello, base64-encoded as aGVsbG8=.
curl -s \
-H 'X-DEV-TOKEN: dev-token' \
-H 'Content-Type: application/json' \
-d '{
"keyId": "demo-identity",
"command": {
"type": "arbitrary",
"authorityId": "arbitrary",
"artifact": {
"scheme": "ECDSA",
"hash": "SHA256",
"data64": "aGVsbG8="
}
}
}' \
http://localhost:8080/v2/keeper/sign
The response contains the Base64 signature and key generation:
{
"signature64": "...",
"type": "ECDSA",
"generation": 1,
"imposters": []
}
Verify
Replace signature-from-sign-response with signature64 from the sign response.
curl -s \
-H 'X-DEV-TOKEN: dev-token' \
-H 'Content-Type: application/json' \
-d '{
"keyId": "demo-identity",
"command": {
"type": "arbitrary",
"artifact": {
"scheme": "ECDSA",
"hash": "SHA256",
"data64": "aGVsbG8="
}
},
"signature64": "signature-from-sign-response"
}' \
http://localhost:8080/v2/keeper/sign/verify
Expected response:
{ "valid": true }
valid: true confirms that the signature matches the message and key. Verification does not evaluate authority policy. An executing application must also check the expected key, action, expiry, and replay rules.
Turn the smoke test into a governed integration
- Define the action schema and effects, then use Authorities to replace
arbitrarywith a structured authority. - Make the downstream service reject the action unless proof for the exact governed intent verifies.
- Use Quorum Modes before creating high-risk keys.
- Use Build and Features to select only the features and platforms your deployment needs.
- Use Authentication and Authorization before leaving local development.