Quickstart
From zero to encrypted round-trip in 5 minutes — copy, paste, run. Uses OAuth 2.0 client-credentials against an existing key.
Quickstart
Do a full encrypt / decrypt round-trip against ANKASecure staging in 5 minutes. Every command below is copy-paste ready — replace only the four placeholder variables and run.
Before you start
You need three things from your platform administrator:
- A
client_idandclient_secret(UUIDs) for an application workload of a tenant on staging. - A
kid(key identifier) of a key already provisioned in that tenant — with algorithm operations that includeencrypt/decrypt. - The
tenant_id(UUID) of the tenant those credentials belong to.
This Quickstart uses only the runtime plane — the client_credentials grant. The kid must already exist, provisioned by an admin using the password grant on /api/v3/admin/tenants/{tenantId}/keys (see the AES-256 recipe for the full admin-plus-runtime flow, or POST /api/v3/admin/tenants/{tenantId}/keys for the endpoint reference).
You also need curl and jq on your terminal (Linux, macOS, WSL, or Git Bash on Windows). Both are one-line installs on every OS.
Set the four variables once so the rest of the guide reads cleanly:
export BASE_URL="https://staging.ankatech.co"
export CLIENT_ID="00000000-0000-0000-0000-000000000000" # UUID from admin
export CLIENT_SECRET="••••••••••••••••••••••••••••••••" # secret from admin
export KID="key_quickstart_demo" # provisioned keyStep 1 — Get a Bearer token (OAuth 2.0 client-credentials)
The Auth API follows RFC 6749 strictly — the request body is application/x-www-form-urlencoded, not JSON.
export TOKEN=$(curl -s -X POST "$BASE_URL/api/v3/auth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
| jq -r .access_token)
echo "Token: ${TOKEN:0:40}..."If you see an eyJ… prefix, the JWT is valid for the next 10 hours (expires_in: 36000). Renew any time by calling the same endpoint again — client-credentials grants have no refresh token.
Not working? See Authentication → Common errors.
Step 2 — Encrypt a payload
The payload goes in Base64 — this is a requirement of the JWE spec, not a convenience.
# Base64-encode "sensitive data" (or any UTF-8 string / binary blob)
export DATA_B64=$(printf "%s" "sensitive data" | base64 -w0)
echo "Payload (base64): $DATA_B64"
# Encrypt — returns a JWE token as a JSON object
curl -s -X POST "$BASE_URL/api/v3/crypto/encrypt" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"kid\": \"$KID\",
\"data\": \"$DATA_B64\"
}" | jq | tee /tmp/encrypt-response.jsonResponse shape:
{
"jweToken": {
"protected": "eyJhbGciOiJSU0EtT0FFUC01MTIiLCJlbmMiOiJBMjU2R0NNIn0",
"recipients": [ { "encrypted_key": "..." } ],
"iv": "...",
"ciphertext": "...",
"tag": "..."
},
"keyRequested": "key_quickstart_demo",
"materialVersion": 1,
"algorithmUsed": "RSA-OAEP-512+A256GCM",
"warnings": []
}algorithmUsed reveals what the tenant policy resolved for your kid — the algorithm is never something you specify at call time. If the policy rotates tomorrow to a hybrid PQC pair (say X25519+ML-KEM-768+A256GCM), your code keeps working — only algorithmUsed changes.
Save the whole jweToken object for the next step:
export JWE_TOKEN=$(jq -c .jweToken /tmp/encrypt-response.json)Step 3 — Decrypt it back
You pass the entire jweToken object back — the kid and algorithm are read from the token's protected header, so there is no separate kid field on decrypt.
curl -s -X POST "$BASE_URL/api/v3/crypto/decrypt" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"jweToken\": $JWE_TOKEN
}" | jqResponse:
{
"decryptedData": "c2Vuc2l0aXZlIGRhdGE=",
"keyRequested": "key_quickstart_demo",
"materialVersion": 1,
"algorithmUsed": "RSA-OAEP-512+A256GCM",
"warnings": []
}decryptedData is Base64 — decode it to verify the round-trip:
echo "c2Vuc2l0aXZlIGRhdGE=" | base64 -d
# → sensitive dataMatch against the original. 🎉
Try it from this portal (no terminal needed)
Every endpoint above has a Try It button on its API Reference page:
- Open
POST /api/v3/auth/token→ in Body switch tox-www-form-urlencoded→ fillgrant_type=client_credentials,client_id,client_secret→ Send → copy theaccess_tokenvalue. - Open
POST /api/v3/crypto/encrypt→ click the 🔒 auth icon → paste the token → fillkidanddata(Base64) → Send. Copy the wholejweTokenobject from the response. - Open
POST /api/v3/crypto/decrypt→ same auth token → pastejweTokenas the body → Send.
The server default is already set to staging.ankatech.co, so you never leave the browser.
What just happened
- Your application never mentioned an algorithm — the tenant's policy resolved
kid→ algorithm at call time. - The
algorithmUsedfield on encrypt and decrypt tells you what was actually used — useful for logs but never for control flow. - If the admin rotates the key material or changes the policy tomorrow, the same code keeps working — only
materialVersionoralgorithmUsedin the response changes. - Every call was recorded in the audit trail under this tenant, correlated to the JWT that authorised it.
That is crypto agility — the whole point of the platform.
Where to go next
| I want to… | Read |
|---|---|
| Understand Bearer, permissions, token rotation | Authentication |
| Switch to production | Environments & Credentials |
| Sign and verify (not just encrypt) | POST /api/v3/crypto/sign |
| Encrypt large files (streaming) | POST /api/v3/crypto/encrypt/stream |
| Create a key (admin only) | POST /api/v3/admin/tenants/{tenantId}/keys |
Discover valid kty and algorithm combinations | GET /api/v3/algorithms |
| See every API operation | API Reference |
Updated 10 days ago