Skip to content

Authentication

All elasticStage authentication is served by a single OAuth 2.1 / OpenID Connect authorization server. Every token — whether for a third-party integration or a first-party dashboard — is issued and signed there, and every API validates it against the server’s public keys (JWKS).

  • Issuer: https://auth.staging.elasticstage.com/api/auth (staging)
  • JWKS: https://auth.staging.elasticstage.com/api/auth/jwks

Send the resulting token on every request as Authorization: Bearer <token>.

The server publishes standard metadata — point an OAuth/OIDC client library at these and it configures the endpoints below automatically:

Document URL
OpenID Connect config https://auth.staging.elasticstage.com/.well-known/openid-configuration
OAuth Authorization Server https://auth.staging.elasticstage.com/.well-known/oauth-authorization-server/api/auth

All are under the issuer base (/api/auth):

Purpose Endpoint
Authorize (start the flow) GET /api/auth/oauth2/authorize
Token (exchange & refresh) POST /api/auth/oauth2/token
Dynamic client registration POST /api/auth/oauth2/register
UserInfo (OIDC claims) GET /api/auth/oauth2/userinfo
Token introspection POST /api/auth/oauth2/introspect
Token revocation POST /api/auth/oauth2/revoke
JWKS (public signing keys) GET /api/auth/jwks

Third-party integrations (the elasticStage Shopify app is one) use the Authorization Code grant with PKCE. Public clients (SPAs, native apps) are supported and use no client secret.

Register once to get a client_id, either way:

  • Dynamic Client RegistrationPOST /api/auth/oauth2/register (RFC 7591):

    Terminal window
    curl -X POST https://auth.staging.elasticstage.com/api/auth/oauth2/register \
    -H "Content-Type: application/json" \
    -d '{
    "client_name": "My Integration",
    "redirect_uris": ["https://your-app.example.com/callback"],
    "token_endpoint_auth_method": "none",
    "grant_types": ["authorization_code", "refresh_token"]
    }'
  • Or ask elasticStage to provision one for you.

  1. Create a PKCE verifier and challenge.

    Terminal window
    # 43–128 char high-entropy string
    code_verifier=$(openssl rand -base64 64 | tr -d '\n=+/' | cut -c1-64)
    code_challenge=$(printf '%s' "$code_verifier" \
    | openssl dgst -sha256 -binary \
    | openssl base64 | tr '+/' '-_' | tr -d '=\n')
  2. Send the user to the authorize endpoint. They sign in on the elasticStage login page and consent to the requested scopes.

    GET https://auth.staging.elasticstage.com/api/auth/oauth2/authorize
    ?response_type=code
    &client_id=YOUR_CLIENT_ID
    &redirect_uri=YOUR_REGISTERED_REDIRECT_URI
    &scope=openid%20releases:read%20orders:read%20orders:create%20offline_access
    &code_challenge=CODE_CHALLENGE
    &code_challenge_method=S256
    &state=CSRF_TOKEN

    On approval they’re redirected back to your redirect_uri with ?code=...&state=....

  3. Exchange the code for tokens. Send the original code_verifier.

    Terminal window
    curl -X POST https://auth.staging.elasticstage.com/api/auth/oauth2/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d grant_type=authorization_code \
    -d code=AUTHORIZATION_CODE \
    -d redirect_uri=YOUR_REGISTERED_REDIRECT_URI \
    -d client_id=YOUR_CLIENT_ID \
    -d code_verifier=CODE_VERIFIER

    The response contains an access_token, its expires_in, and — when you requested offline_access — a refresh_token.

  4. Call the API with the access token:

    Terminal window
    curl https://api.staging.elasticstage.com/store/v1/releases \
    -H "Authorization: Bearer $ACCESS_TOKEN"
  5. Refresh when it expires, reusing the token endpoint:

    Terminal window
    curl -X POST https://auth.staging.elasticstage.com/api/auth/oauth2/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d grant_type=refresh_token \
    -d refresh_token=YOUR_REFRESH_TOKEN \
    -d client_id=YOUR_CLIENT_ID
Scope Grants
openid Confirm the user’s identity (enables OIDC).
profile Access the user’s basic profile.
email Access the user’s email address.
offline_access Issue a refresh token so you can renew the access token.
Scope Grants
creator:read Read the connected creator profile.
releases:read Read the creator’s releases and their products.
releases:write Create, update, and delete the creator’s releases.
orders:read Read fulfilment orders for the connected creator.
orders:create Place fulfilment orders.
shipping:read Quote shipping rates and read the service catalogue.
webhooks:read Read webhook subscriptions and their delivery history.
webhooks:create Create webhook subscriptions.
webhooks:update Update webhook subscriptions and send test/sandbox events.
webhooks:delete Delete webhook subscriptions.

The Creator API accepts bearer JWTs issued by the same authorization server and validated against its JWKS. Present the token exactly the same way:

Terminal window
curl https://api.staging.elasticstage.com/creator/api/v1/creators \
-H "Authorization: Bearer $ACCESS_TOKEN"

Tokens are multi-audience — a first-party session token is minted for both the Store and Creator APIs — and carry the caller’s claims. A caller is either a global admin (sees every creator) or organisation-scoped (sees only creators in their organisation, via the org_id / org_role claims); the API enforces this automatically.

  • Introspect a token’s active state and claims: POST /api/auth/oauth2/introspect.
  • Revoke an access or refresh token: POST /api/auth/oauth2/revoke.
  • UserInfo for the OIDC profile of the current token: GET /api/auth/oauth2/userinfo.
Status Code Meaning
401 UNAUTHORIZED Missing, malformed, or expired token. A WWW-Authenticate: Bearer challenge header is returned.
403 FORBIDDEN Valid token, but missing a required scope or not permitted to access the resource.

See Errors & conventions for the full error envelope.