Skip to main content
Version: 0.6

Konstruct 0.6.2

Released: July 2026

Highlights

  • Microsoft Entra ID authentication (opt-in) — an external service (for example a developer portal) can call the Konstruct API with a Microsoft Entra access token instead of a shared API key; validated against Entra's JWKS with tenant and scope checks
  • Group-id role mapping — team role mappings can now match an Azure/Entra group object ID in addition to a group name, so one mapping works for both interactive SSO login and direct Entra tokens
  • Fixed: IaC variable escaping — application variable values containing quotes (HCL list(object), JSON objects) no longer produce invalid YAML in the generated Workspace manifest

Microsoft Entra ID authentication

Konstruct can now accept a Microsoft Entra ID access token on the Authorization: Bearer header as an alternative to a shared API key. This lets an external service — for example a developer portal — call the Konstruct API with the signed-in user's identity propagated end to end, instead of sharing a single long-lived credential.

Opt-in — off by default

This path is disabled unless configured. With the Entra environment variables unset, authentication behaves exactly as before: Dex SSO login, the custom session JWT, and konst_api_* / konst_mcp_* API keys are all unchanged.

How it works

  • Konstruct validates the token against Entra's JWKS — signature, issuer (iss), audience (aud), and expiry (exp) — pins the directory tenant (tid), and optionally requires a scope.
  • The authenticated identity resolves to a Konstruct role through the existing team/group mapping: the token's groups are matched against your teams, exactly like Dex/Azure users.
  • The new validation branch sits alongside the API-key and session-JWT paths. Each path verifies its own token format, so they can never accept a token issued for a different path.

Microsoft Entra setup

Before enabling the feature, register two applications in your Entra tenant.

1. The Konstruct API app — the resource that receives and validates tokens:

  • Expose an API → set the Application ID URI and add a delegated scope (e.g. access_as_user).
  • Token configuration → add a groups claim (Security groups) to access tokens, so tokens carry the caller's group membership.
  • Manifest → set api.requestedAccessTokenVersion: 2 to issue v2 tokens. For v2, aud is the bare client-ID GUID — that value is what ENTRA_AUDIENCE expects.
  • API permissions → Microsoft Graph → Application permission Group.Read.All, then Grant admin consent. Required so the team form's group picker can list Azure groups (GET /api/v1/sso/{provider}/groups).
  • Expose an API → Authorized client applications → pre-authorize each client that calls the scope (e.g. your portal's client app, or the Azure CLI for testing).
  • Copy this app's client IDENTRA_AUDIENCE, and the directory (tenant) IDENTRA_TENANT_ID.

2. The client app — what signs users in (e.g. your developer portal):

  • Authentication → Add platform → Single-page application (or Web) → set the redirect URI to your app's origin.
  • API permissions → My APIs → select the Konstruct API app → Delegatedaccess_as_userGrant admin consent.

3. Security groups:

  • Create the security groups and add users; note each group's object ID (GUID).
  • Map a group to a Konstruct role from the team form. The mapping stores both the group name and its object ID, so it resolves whether a token carries one or the other.
Groups overage

A user who belongs to more than ~200 groups receives a distributed-claims pointer instead of an inline groups claim. To avoid this, emit only app-relevant groups via Groups assigned to the application (requires Entra ID P1/P2) and assign the relevant groups to the API app.

Configuration

Enable it by setting (at minimum) the tenant and audience on konstruct-api:

VariableRequiredDescription
ENTRA_TENANT_IDto enableEntra directory (tenant) GUID. Builds the default v2 issuer and is enforced against the token's tid
ENTRA_AUDIENCEto enableValue the token's aud must equal — the API app's client-ID GUID for v2 tokens (not the api://… form)
ENTRA_REQUIRED_SCOPEoptionalRequired value in the token's scp scopes or roles; empty disables the scope check
ENTRA_ISSUERoptionalIssuer override for v1.0 (sts.windows.net) or sovereign clouds; derived from the tenant when empty

The feature turns on only when both ENTRA_TENANT_ID and ENTRA_AUDIENCE are set.

Team role mappings: match by group name or ID

A team role mapping now carries two group identifiers, and role resolution matches on either one:

FieldMatched againstUsed by
oidcGroupGroup nameDex/Civo login tokens (existing behavior)
oidcGroupIdGroup object ID (GUID)Azure/Entra tokens

Different login paths put different identifiers in the token — Dex/Civo emit group names, while Azure and direct Entra tokens emit group object IDs. Storing both on the mapping lets a single team serve every path.

In the UI, selecting a group in the team form now captures and saves both values automatically — you still pick the group by name; the object ID is recorded behind the scenes. Existing name-only mappings keep working unchanged: oidcGroupId is optional and fully backward compatible.

Fixed: IaC variable values with quotes now produce valid YAML

Application variable values that contained double quotes — for example an HCL list(object) or a JSON object — were written raw into the generated Workspace manifest, producing invalid YAML that failed to parse:

value: "[{ name = "pk", type = "S" }]"   # parser error

The application-operator now escapes variable values for a YAML double-quoted scalar before rendering them into the Workspace manifest. Simple values are unaffected — they render byte-for-byte identically, so existing catalog items are not changed; only values that previously broke the manifest are corrected. The fix ships with unit tests covering simple, HCL list(object), and JSON-object values with exact round-trip assertions.

If you had a catalog item with a variable value that failed to deploy because of quoting, re-deploying on 0.6.2 renders valid YAML with no changes on your side.

Upgrade notes

Update the targetRevision in your platform team's Konstruct Argo CD Application manifest to 0.6.2:

spec:
source:
chart: konstruct
repoURL: oci://europe-west2-docker.pkg.dev/civo-com/charts
targetRevision: 0.6.2

Commit and push — Argo CD syncs the new version automatically. No manual migration steps are required.

  • Microsoft Entra authentication is opt-in. Existing deployments are unaffected until you set ENTRA_TENANT_ID and ENTRA_AUDIENCE.
  • The oidcGroupId field on team role mappings is optional and backward compatible with existing name-only mappings.

What's next?