Skip to main content

Before you begin

Roles & credentials
  • Organization member credentials for the Sutro API (email and password).
Tools
  • curl, jq, uuidgen, and the jwt CLI.
  • Node.js (optional) if you prefer the JavaScript example.
  • UNIX shell (macOS/Linux) or WSL on Windows.
Variables you’ll need
  • <ORG_MEMBER_EMAIL> — Email for an organization member.
  • <ORG_MEMBER_PASSWORD> — Password for that account.
  • <COMMON_NAME> — Friendly name for the certificate to generate (e.g., “Staging key”).
  • <JWT_ISSUER> — Issuer string to embed in Builder JWTs (e.g., your org slug or auth issuer).
All placeholders appear in angle brackets and must be replaced before running commands.

Steps

Sutro walks you through each credential step so you stay in charge of the entire security chain—from login to Builder-issued tokens—with Sutro validating every move.
1

Authenticate as an organization member

Use your organization member credentials to obtain an access token.
curl -H "Content-Type: application/json" \
     -X POST \
     -d '{"email":"<ORG_MEMBER_EMAIL>","password":"<ORG_MEMBER_PASSWORD>"}' \
     -o auth.json \
     https://sapi.withsutro.com/login

# Store the access token for subsequent requests
ORG_MEMBER_JWT=$(jq -r '.access_token' < auth.json)

Replace these placeholders

PlaceholderMeaning
<ORG_MEMBER_EMAIL>Email of an organization member with login access
<ORG_MEMBER_PASSWORD>Password for that account
2

Initialize your organization

Provision a certificate and private key for signing Builder JWTs.
curl -H "Content-Type: application/json" \
     -H "Authorization: Bearer ${ORG_MEMBER_JWT}" \
     -X POST \
     -d '{"commonName": $COMMON_NAME, "jwtIssuer": $JWT_ISSUER}' \
     -o certs.json \
     https://sapi.withsutro.com/initialization

# Save the certificate and private key to files and capture the certificate ID and API Client Identifier
CERTIFICATE_ID=$(jq -r '.certificate.id' < certs.json)
API_CLIENT_IDENTIFIER=$(jq -r '.apiClientIdentifier' < certs.json)
jq -r '.privateKey' < certs.json > sutro.key
jq -r '.certificate.content' < certs.json > sutro.crt

Replace these placeholders

PlaceholderMeaning
<COMMON_NAME>Friendly label for the certificate (e.g., “Production key”)
<JWT_ISSUER>The value you expect to place in the iss claim of Builder JWTs
The file sutro.key contains your private key. Store it securely and restrict file permissions.
3

Create a Builder

Create a Builder and record its sid. You’ll use this value as the JWT subject (sub).
BUILDER_SID=$(uuidgen)
curl -H "Content-Type: application/json" \
     -H "Authorization: Bearer ${ORG_MEMBER_JWT}" \
     -X POST \
     -d "{\"sid\": \"$BUILDER_SID\"}" \
     -o builder.json \
     https://sapi.withsutro.com/builders
Important: The JWT sub must equal the Builder’s sid.
4

Generate a Builder JWT with the CLI

Use the jwt CLI to sign a short-lived access token with your private key.
# Generate a signed Builder JWT (1 hour expiration)
BUILDER_JWT=$(jwt encode --secret @sutro.key \
           -A RS256 \
           --iss "$JWT_ISSUER" \
           --sub "$BUILDER_SID" \
           --aud "https://sapi.withsutro.com" \
           --jti $(uuidgen) \
           --exp=$(($(date +%s) + 3600)))

echo "${BUILDER_JWT}"

Replace or verify these values

FieldMeaning
issMust match <JWT_ISSUER> you set during initialization
subMust equal the Builder’s sid (${BUILDER_SID})
audAudience of the Sutro API: https://sapi.withsutro.com
expExpiration time (Unix seconds). The example uses 1 hour.
5

Generate a Builder JWT in JavaScript (optional)

If you prefer Node.js:
import crypto from "node:crypto";
import jwt from "jsonwebtoken";
import fs from "node:fs";

const privateKey = fs.readFileSync("sutro.key", "utf8");
const builderSid = process.env.BUILDER_SID; // set from the previous step
const issuer = process.env.JWT_ISSUER;      // set to <JWT_ISSUER>

const accessToken = jwt.sign(
  {},
  privateKey,
  {
    algorithm: "RS256",
    expiresIn: "1h",
    jwtid: crypto.randomUUID(),
    audience: "https://sapi.withsutro.com",
    subject: builderSid,
    issuer,
  }
);

console.log(accessToken);
Set BUILDER_SID and JWT_ISSUER in your environment before running the script.
6

Verify your JWT (optional)

  • Inspect claims and signature at https://jwt.io/.
  • Your public certificate is in sutro.crt (PEM).
# View the PEM-encoded public certificate
cat sutro.crt
Your organization keys and Builder JWT flow are locked down—keep building knowing every API call is authenticated and auditable.

Reference

  • POST /login — Exchange organization member credentials for a JWT used to administer your organization.
  • POST /initialization — Provision a certificate and private key used to sign Builder JWTs.
  • POST /builders — Create a Builder and obtain its sid.
  • Builder JWT claimsiss (issuer), sub (Builder sid), aud (https://sapi.withsutro.com), jti, exp.

Next steps