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:

  1. A client_id and client_secret (UUIDs) for an application workload of a tenant on staging.
  2. A kid (key identifier) of a key already provisioned in that tenant — with algorithm operations that include encrypt / decrypt.
  3. 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 key

Step 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.json

Response 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
  }" | jq

Response:

{
  "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 data

Match against the original. 🎉


Try it from this portal (no terminal needed)

Every endpoint above has a Try It button on its API Reference page:

  1. Open POST /api/v3/auth/token → in Body switch to x-www-form-urlencoded → fill grant_type=client_credentials, client_id, client_secretSend → copy the access_token value.
  2. Open POST /api/v3/crypto/encrypt → click the 🔒 auth icon → paste the token → fill kid and data (Base64) → Send. Copy the whole jweToken object from the response.
  3. Open POST /api/v3/crypto/decrypt → same auth token → paste jweToken as 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 algorithmUsed field 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 materialVersion or algorithmUsed in 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 rotationAuthentication
Switch to productionEnvironments & 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 combinationsGET /api/v3/algorithms
See every API operationAPI Reference

Did this page help you?