Create your first context and signing key
By the end of this guide, your VTA has a context set aside for one application, with a signing key inside it that an application can sign with.
Prerequisites
Affinidi hosts a VTA in one of two modes. Isolated runs in an AWS Nitro Enclave, a Trusted Execution Environment (TEE), with hardware-rooted attestation, keys and data. Shared runs on a shared network, for evaluation and development purposes only.
- A running VTA with
pnmconnected. See Deploy VTA appliance or Self-hosted (open source) if you haven’t deployed one yet. - Your VTA’s slug to hand.
- Isolated mode: the
VTA slugprinted bypnm bootstrap connect. - Shared mode or self-hosted: the
slugvalue printed bypnm setup, which ismy-vtain those guides.
- Isolated mode: the
pnm --vta <vta-slug> healthshows ✓ on every check.- Super-admin access to the VTA, which creating a top-level context needs. The admin credential from
pnm bootstrap connect, or frompnm setupin Shared mode or on a self-hosted VTA, is a super-admin.
Steps
Create a context
A context is a named namespace for the keys and other items you create inside it. Identities scoped to that context or to a parent context can reach them, as can super-admins.
pnm --vta <vta-slug> contexts create \
--id my-app \
--name "My App"Replace <vta-slug> with your VTA’s slug, from the Prerequisites above.
Expected output:
VTA: <vta-slug>
DID: did:webvh:QmVE1TQeCtg3aavpTqasqencJpagRr8JKdGRyoZ5Qx6kRp:your-appliance.vta.affinidi.io
Context created:
ID: my-app
Name: My App
Base Path: m/26'/2'/2'Mint a signing key
Every context starts empty. Mint an Ed25519 key inside it so there’s something to sign with.
pnm --vta <vta-slug> keys create \
--key-type ed25519 \
--context my-app \
--label "my-app-key-1"Expected output:
VTA: <vta-slug>
DID: did:webvh:QmVE1TQeCtg3aavpTqasqencJpagRr8JKdGRyoZ5Qx6kRp:your-appliance.vta.affinidi.io
Key created:
Key ID: m/26'/2'/2'/0'
Key Type: ed25519 (classical signing)
Derivation Path: m/26'/2'/2'/0'
Public Key: z6MkvZqY2CbpWQmbjuuNshtAptH8qbFaCGk3w6Jt72xBXiGi
Status: active
Label: my-app-key-1
Created At: 2026-09-11 19:42:44 +08:00The Key ID is the same value as the Derivation Path: a BIP-32 path, not a short opaque ID. Keep it: an application passes this value to the VTA SDK’s sign call to sign with the key, and the private key stays on the VTA.
Confirm
Confirm the key exists and is active:
pnm --vta <vta-slug> keys list --context my-app --status activeYour new key appears in the list, labelled my-app-key-1, with status active and derivation path m/26'/2'/2'/0'.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
context already exists: my-app | A context with this ID already exists on the VTA. | Pick a different --id, or use the existing context instead of creating a new one. |
pnm contexts create fails with super admin required | Your session is not a super-admin. | Run pnm auth status to check which identity you are connected as, then use a super-admin credential. |
pnm keys list returns no keys | The key was minted in a different context, or --context doesn’t match. | Re-run pnm --vta <vta-slug> keys list --context my-app without --status to see every key, active or not. |
Next steps
- Sign application payloads without exposing your keys: Provision an application credential for this context and start signing with the key you just minted.
- Keys and contexts: Understand how context isolation and key derivation work underneath this guide.
- Mint, inspect, and retire signing keys: list what a context holds, replace a key whose label is out of date, and take one out of service.
- Glossary: decode the terms you see in
pnmoutput, fromVTA slugtoPCR0.
Glad to hear it. Thanks for letting us know.
Sorry to hear that. Thanks for letting us know.