API Reference

Authentication

How to authenticate API requests using OIDC tokens from Zitadel.

flex.plane uses OIDC (OpenID Connect) for authentication, powered by Zitadel. Every API request that goes beyond anonymous access requires a valid Bearer token.

Obtain a token

Your OIDC token comes from the Zitadel instance deployed as part of your flex.plane installation. There are several ways to obtain one depending on your use case.

Interactive login (browser)

The portal handles this automatically. When you log into the portal, it performs the OIDC Authorization Code flow with PKCE and stores the resulting token. If you are building a custom frontend, use the same flow against your Zitadel issuer.

Service account (machine-to-machine)

For automation, CI/CD pipelines, or backend integrations, create a service account in Zitadel and use the Client Credentials grant:

curl -X POST https://auth.example.com/oauth/v2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=<service-account-client-id>" \
  -d "client_secret=<service-account-client-secret>" \
  -d "scope=openid profile email"

The response contains an access_token you can use as a Bearer token.

Personal access token

Zitadel also supports personal access tokens (PATs) for individual users. These are long-lived tokens suitable for development and scripting. Generate one in the Zitadel console under your user profile.

Send authenticated requests

Include the token in the Authorization header of every GraphQL request:

curl -X POST https://flexplane.example.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -d '{"query": "{ vms { id name status } }"}'

If you are working within a specific VDC, add the FlexPlane-VDC-ID header as well:

curl -X POST https://flexplane.example.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
  -H "FlexPlane-VDC-ID: production" \
  -d '{"query": "{ vms { id name status } }"}'
Never include tokens in URL query parameters. Always use the Authorization header to prevent tokens from leaking into server logs, browser history, or referrer headers.

Understand token claims

The OIDC token contains claims that flex.plane uses to determine your identity and permissions. Key claims:

ClaimPurpose
subYour unique user ID in Zitadel.
emailYour email address.
nameYour display name.
urn:zitadel:iam:org:project:rolesA map of your assigned roles. flex.plane reads this to determine USER, ADMIN, VDC_USER, VDC_ADMIN access.

The role claim structure maps Zitadel project roles to flex.plane's role model:

  • Tenant-wide roles (USER, ADMIN) grant access across the entire tenant.
  • VDC-scoped roles (VDC_USER, VDC_ADMIN) grant access within specific Virtual Datacenters. These roles are prefixed with the VDC ID in the token claims.

The orchestrator extracts these claims from the token on every request and makes them available to resolvers via the request context. You do not need to pass role information explicitly. It is all derived from the token.

Tokens have a limited lifetime (typically 1 hour). Your client should handle token refresh automatically. The portal uses silent token renewal via Zitadel's OIDC session management.

If a request fails with an authorization error, verify that:

  1. Your token has not expired.
  2. Your user has the required role for the operation (check the @hasRole directive in the schema).
  3. If using VDC-scoped operations, you have a VDC_USER or VDC_ADMIN role for the target VDC, and the FlexPlane-VDC-ID header is set.