Skip to content

Quickstart: authenticate

Every Legion API call carries a Bearer token issued by Keycloak, Legion’s identity provider. This page gets you a token, shows you what it contains, and proves it works with a real call. At the end you have everything the rest of the quickstarts build on.

Before you start, you need:

  • An Orion account that belongs to at least one organization. If you can sign in at us-gov.orionc2.com, you are ready.
  • curl or Python 3.10+.

The environments used below:

ServiceURL
Legion APIhttps://api.usg.legion.picogrid.com
Keycloak (identity)https://auth.hopper.west.prod.govcloud.legion.picogrid.com
  1. Request a token.

    Keycloak issues tokens from its token endpoint. You authenticate with the same username and password you use for Orion, through the public frontend...orion client. The request body is form-encoded, not JSON.

    Terminal window
    curl -s "https://auth.hopper.west.prod.govcloud.legion.picogrid.com/realms/legion/protocol/openid-connect/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=password" \
    -d "client_id=frontend...orion" \
    -d "username=you@example.com" \
    --data-urlencode "password=YOUR_PASSWORD"

    A successful response looks like this:

    {
    "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6...",
    "expires_in": 1800,
    "refresh_expires_in": 1800,
    "token_type": "Bearer",
    "scope": "email profile"
    }

    access_token is what you will send on every API call. expires_in is seconds: tokens live 30 minutes, after which requests return 401 and you request a new one the same way.

  2. Send it on a request.

    Pass the token in the Authorization header. The call below lists the organizations your account belongs to, which is also the first thing you need for every other quickstart.

    Terminal window
    curl -s "https://api.usg.legion.picogrid.com/v3/me/orgs" \
    -H "Authorization: Bearer $TOKEN"
    {
    "results": [
    {
    "organization_id": "2b1c9f04-8f6e-4c1a-9a67-1d2f3e4a5b6c",
    "organization_name": "Example Org",
    "organization_role": "ADMIN"
    }
    ]
    }

    If you see your organization listed, authentication works end to end.

  3. Save the organization id.

    Almost every Legion endpoint is organization-scoped and requires the X-ORG-ID header alongside the token. Calling one without it returns:

    { "status": "error", "code": 400,
    "message": "Organization ID is required in either X-ORG-ID header or org-id query parameter" }

    Copy the organization_id from step 2. The next quickstart, Create your first entity, uses it on every call.

Troubleshooting

ResponseCauseFix
401 invalid_grantWrong username or passwordCredentials are the same ones Orion accepts; the username is your full email address.
400 unauthorized_clientPassword grant disabled for this environmentUse the browser-token fallback above.
401 after it worked earlierToken expired (30 min)Request a new token; nothing else changes.
400 Organization ID is requiredOrg-scoped endpoint called without X-ORG-IDAdd the header with the id from step 3.

Next steps

Version 3.14.0 · commit 0771262