---
title: "Governance Platform v1.2.0 Release Notes"
description: "Customer-facing release status for the Governance Platform v1.2.0 minor release."
source: "Guardian Platform"
---
Governance Platform v1.2.0 is a stable minor release for the v1 customer release
line. It publishes refreshed runtime images, Helm charts, release manifest
metadata, and customer package artifacts from validated release source refs. It
adds scoped, expiring, and project-bound API keys that work across the platform
services, public identifiers on Governance Service routes, and faster credential
revocation for the gateway stack.

This release includes **breaking API changes** and **database migrations that
cannot be reversed**. Read [Breaking Changes](#breaking-changes) and
[Before Installing](#before-installing) before upgrading.

## Included Runtime Components

- Governance Studio
- Governance Service
- Auth Service
- Integrity Service
- EQTY PDFGen
- Gateway stack: LLM Gateway, Control Plane, and Console (opt-in)
- Governance Platform deployment charts

## Breaking Changes

These changes affect clients that call the platform APIs directly and operators
of the gateway stack. Governance Studio is already updated for all of them.

### Governance Service API

- **Project policy is renamed to applied policy.** Request and response fields,
  query parameters, and permission names change, with no aliases for the old
  names:

  | Before                                              | After                                               |
  | --------------------------------------------------- | --------------------------------------------------- |
  | `projectPolicyId`, `projectPolicy`                  | `appliedPolicyId`, `appliedPolicy`                  |
  | `projectPolicyControlId`, `projectPolicyControlIds` | `appliedPolicyControlId`, `appliedPolicyControlIds` |
  | `projectPolicyName`, `projectPolicySlug`            | `appliedPolicyName`, `appliedPolicySlug`            |
  | `apply_project_policies` permission                 | `apply_policies`                                    |
  | `archive_project_policies` permission               | `archive_applied_policies`                          |

  An old `projectPolicyId` or `projectPolicyControlId` query parameter is ignored
  rather than rejected, so a client that still sends one receives unfiltered
  results.

- **Project get and archive routes moved under the organization.** The previous
  paths are removed.

  | Before                                      | After                                                             |
  | ------------------------------------------- | ----------------------------------------------------------------- |
  | `GET /api/v1/projects/{projectId}`          | `GET /api/v1/organizations/{orgId}/projects/{projectId}`          |
  | `PUT /api/v1/projects/{projectId}/archived` | `PUT /api/v1/organizations/{orgId}/projects/{projectId}/archived` |

  To look up a project by UUID without an organization, use
  `GET /api/v1/projects/by-uuid/{projectUUID}`.

- **A numeric control id on the applied control route names the applied copy.**
  On `GET /api/v1/projects/{projectId}/policies/{appliedPolicyId}/controls/{appliedPolicyControlId}`,
  a numeric segment is now the applied policy control id, not the base control
  id. A caller still passing a base control id can receive a different control
  rather than an error. Address controls by `code:<control-code>` instead, which
  is stable across every project that applied the policy.

- **Required fields are enforced.** These requests now return `400`:

  | Endpoint                                      | Rejected when                                                                                            |
  | --------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
  | `POST /api/v1/organizations/{orgId}/projects` | The description is empty, whitespace only, or absent                                                     |
  | `POST /api/v1/organizations/{orgId}/policies` | The policy description, or any nested control's description, is missing, or `type` is missing or unknown |
  | `POST /api/v1/policies/convert`               | A Controls row is missing its description, title, or control code                                        |
  | `POST /api/v1/activity-logs`                  | `action` or `resource` is blank                                                                          |

- **UUIDs are returned in `urn:uuid:` form.** Organizations, projects, custom
  indicators, indicator applications, and evaluation results serialize their
  UUIDs as `urn:uuid:<uuid>`, and references to them such as `indicatorId` and
  `applicationUuid` follow the same form. Governance Service returns stored
  content identifiers as `urn:cid:<cid>`. Clients that compare these values
  against bare UUIDs or CIDs must normalize them first.

- **Policies without a content identifier can no longer be applied.** Existing
  policies receive a content identifier during the upgrade only if they had
  already been applied to a project. A policy that was never applied returns an
  error when applied and must be recreated.

- **`400` error bodies use one shape.** Archive, credential revocation, and
  indicator endpoints that returned extra `status`, `path`, and `method` fields on
  a `400` now return only `{"error": "..."}`.

### Auth Service API

- **API keys must expire.** `POST /api/v1/api-keys` requires `expiresAt`, set in
  the future and no more than 365 days ahead. Existing keys without an expiry are
  given one 365 days after the upgrade. Expired keys report `status: expired` and
  return `401 API key has expired`.
- **API key creation validates scopes and descriptions.** The request returns
  `400` when the description is missing, when a scope is unknown or not held by
  the creator, when `*` is combined with other scopes, when `*` is requested by
  anyone other than an organization owner, or when `*` or an empty scope list is
  requested for a key bound to a project.
- **API keys cannot manage API keys.** The `/api/v1/api-keys` routes accept only
  a signed-in session. Requests made with an API key return `403`.
- **Scoped API keys are limited to their scopes.** A key created with specific
  scopes acts only with those scopes, instead of with every permission its holder
  has. Keys created with `*` or no scopes are unchanged.
- **Unknown identity providers are rejected.** `POST /api/v1/auth/claims`
  returns `400 Unknown provider` for an unrecognized `provider`.

### Gateway Stack

- **Agent ids are `urn:uuid:` values.** Existing agent ids are permanently
  rewritten to `urn:uuid:` form during the upgrade, and the separate `agent_uuid`
  field is removed. Update any stored agent ids or integrations that reference
  them.
- **Registration tokens assign the agent id.**
  `POST /v1/agent-registration-tokens` always assigns a `urn:uuid:` agent id and
  returns `400` when the request body includes `agent_id`.
- **Minting a registration token requires `register_agents`.** With
  `auth.bearer.mode=auth_service`, the caller must hold the organization-level
  `register_agents` permission. Previously this was enforced only in Governance
  Studio.
- **Health endpoints return JSON.** LLM Gateway and Control Plane `/health` return
  a JSON body with the service name, timestamp, and version instead of plain-text
  `ok`. Probes that check only the status code are unaffected.

## Changes Since v1.1.1

These changes are grouped by area.

### API Keys and Access

- Choose the scopes and expiry of an API key when you create it. Governance
  Studio lists only the scopes you are allowed to grant, requires at least one,
  and shows each key's scopes and expiry after creation.
- An API key bound to a project acts only on that project for project
  permissions, including when its holder is an organization owner.
  Organization-level permissions (manage organization settings and users, create
  projects, create policies, and register agents) still apply across the
  organization. Keys created for the organization keep access to every project
  the holder can reach.
- API keys work with Integrity Service, checked against Auth Service
  permissions, and with Control Plane routes that check permissions. Control
  Plane routes tied to a signed-in session, such as `/v1/me`, still require one.
  An API key never has Control Plane administrator access.
- Governance Service and Governance Studio honor an API key's permission limits
  instead of the holder's broader roles.
- Adds the `agent_operator` organization role, which can register agents and
  view project data.
- All organization members can view the organization and project member lists.
  Managing members still requires permission, and removed members lose access
  before their session token expires.
- The Auth Service access token lifetime is configurable with
  `auth-service.config.tokenExchange.accessTokenExpirySeconds` when token exchange
  is enabled for Keycloak or Microsoft Entra ID. The default remains `3600`, values
  above `86400` are capped, and the first token after login is still limited by the
  identity provider token's remaining lifetime.

### Identifiers

- Governance Service routes accept more public identifiers alongside numeric
  ids: `urn:cid:` for policies, applied policies, and controls,
  `slug:<slug>@<version>` for policies, and `slug:` for projects. Organizations
  and credentials accept a numeric id or UUID, and indicators accept a UUID or
  `slug:`.
- New policies receive their content identifier when they are created instead of
  when they are first applied.
- Applied policies, credentials, declarations, reviews, and attachments record
  the acting user's DID in `appliedByDid`, `archivedByDid`, `issuedByDid`,
  `revokedByDid`, `submittedByDid`, and `uploadedByDid`. Records created before the
  upgrade keep only the display name.
- File attachments carry a `cid` field. Attachments uploaded before the upgrade
  have an empty value.
- Activity log entries include a `uuid` field in `urn:uuid:` form.

### Governance Studio

- Adds an organization-wide agent page with identity, keys, bound users, project
  associations, and request logs, alongside the existing project agent view.
- Activity, evaluation, and gateway log viewers share one layout: scroll to load
  more, link directly to an entry's detail panel, pin entries, move between
  entries with the arrow keys, and drag across a volume histogram to filter by
  time. Activity log entries link to the resource they describe.
- Lineage View links can open directly to a selected node.
- Breadcrumb selectors are searchable, and filter dropdowns narrow their options
  to match the other active filters.
- The policy editor highlights code and flags JSON problems as you type.
- Credential expiry shows the exact number of days remaining.
- Controls and indicators tables no longer show descriptions, and table search no
  longer matches description text.
- Type-to-confirm dialogs require the exact name, including case.
- Refreshes forms, status indicators, tooltips, charts, error states, and loading
  states for a more consistent interface.

### Gateway Stack

- When a project's gateway configuration enforces revocation, revoking a project
  compliance credential in Governance Studio blocks agent traffic on the next
  request instead of after several minutes.
- Control Plane refreshes project membership credential status in the background,
  up to 100 credentials per `controlPlane.adapter.integrityStatusCacheTTL`
  interval (default `5m`).
- The `builtin.project_membership` plugin accepts `max_status_age_seconds` to deny
  credentials whose revocation status is older than the bound. It is off by
  default. A positive value also denies agent-presented credentials that Control
  Plane has not yet checked, so size it to cover a full refresh of every stored
  membership credential rather than a single interval.
- Control Plane lists the credentials each agent presents at
  `GET /v1/projects/{project_uuid}/agents/{agent_id}/credentials`, with each
  credential reported as active, revoked, not applicable, or unknown, and reports
  expired or revoked project memberships instead of hiding them.
- Agents can enroll with an API key that carries `register_agents` when
  `gateway-stack.llmGateway.authServiceBaseURL` points at the platform Auth
  Service. Enrollment with registration tokens is unchanged.
- Agents record the harness they declare at registration, so agent type filters
  and icons work before an agent sends traffic.
- Plugin artifacts can be stored in Azure Blob Storage. Set
  `LLM_GATEWAY_PLUGIN_ARTIFACT_STORAGE_PROVIDER=azure` and
  `CONTROL_PLANE_PLUGIN_ARTIFACT_STORAGE_PROVIDER=azure` with the matching
  `..._AZURE_*` credentials through `extraEnv` on both `llmGateway` and
  `controlPlane`.
- LLM Gateway can run plugins with a WebAssembly interpreter instead of the
  compiler, for environments where compiled execution is unreliable. Set
  `LLM_GATEWAY_PLUGIN_WASM_INTERPRETER=true` through `llmGateway.extraEnv`.
- LLM Gateway accepts up to 16 presented credentials per request, up from 8, and
  no longer rejects requests with `vc_ambiguous` when several credentials name the
  agent's own DID.

### Fixes

- Integrity Service no longer fails when building a manifest for a lineage graph
  with no computations, and accepts `urn:cid:` identifiers wherever a blob is
  addressed.
- Archiving an applied policy frees its name for reuse and keeps the archived
  record addressable.
- Creating a policy is a single transaction, so a failed control no longer leaves
  a partial policy behind.
- Reissuing a revoked project membership with the same expiration date succeeds.
- Organization owners no longer lose Control Plane administrator access after
  registering an agent.

### Security

- Activity log entries take the acting user from the authenticated request
  rather than from the request body, so an entry cannot be attributed to another
  user.
- Evaluation result listings and lookups are limited to projects the caller can
  access.
- A numeric policy id is checked against the organization in the request path,
  and a numeric control id against its policy.
- Updates Go cryptography and gRPC dependencies for published advisories, pins
  the LLM Gateway Go toolchain, and removes a withdrawn Rust dependency.
- Removes an unused packaging tool from the EQTY PDFGen runtime image, clearing
  the image scan findings it carried.

### Charts and Release Manifest

- Bumps runtime and umbrella Helm charts to `1.2.0` and pins component source
  refs, image tags, and image digests in the release manifest.

## Customer Artifacts

- Release manifest
- Packaged Helm charts and chart digests
- Connected installation package with its checksum
- Optional air-gap package when enabled for the release
- Generated OpenAPI reference
- Generated Helm values reference

## Before Installing

Confirm that the release manifest has `validation.evidence.status` set to
`approved`, and use only the chart versions and runtime image tags recorded in
that manifest. Do not mix v1.2.0 images or charts with earlier v1.1 artifacts.

Update any direct API integration for the [breaking changes](#breaking-changes)
above before upgrading.

### Database Migrations

This release migrates the Governance Service, Auth Service, LLM Gateway, and
Integrity Service databases. Several migrations remove data or rewrite
identifiers, and their down migrations do not restore it:

- Governance Service drops unused columns and superseded UUID columns, and
  renames duplicate policy slugs and archived applied policy slugs by appending
  the row id. Links that used those slugs change.
- Auth Service drops unused session and audit tables, and gives every API key
  without an expiry one 365 days after the upgrade.
- LLM Gateway rewrites every agent id to `urn:uuid:` form.

Plan the upgrade as follows:

1. **Back up all platform databases.** Rolling back to v1.1.1 requires restoring
   this backup.
2. **Schedule a maintenance window.** Scale Governance Service to zero replicas
   before upgrading. The chart runs its migrations at startup, and they cannot
   run safely while a v1.1.1 Governance Service is still serving requests.
3. **Allow time for large tables.** Governance Service rewrites the activity log
   and LLM Gateway rewrites gateway audit records, each in a single transaction
   that holds a lock for its duration.
4. **Use PostgreSQL 13 or later for the gateway database.** The LLM Gateway
   migration enables the `uuid-ossp` extension.
5. **Roll out LLM Gateway before Control Plane** when upgrading the gateway stack.
6. **Upgrade the `governance-platform` chart to `1.2.0`** as described in
   [Upgrade](../deployment/upgrade.mdx), using the chart versions and image tags
   recorded in the release manifest.

## Release Readiness

This release is customer-facing. The deployment repository published the
`platform/v1.2.0` GitHub Release, and the release manifest records approved
manual validation evidence.
That validation covered a staging upgrade from v1.1.1 with Keycloak and external
PostgreSQL. The gateway stack was not enabled in staging and is not covered by it.

## Related

- [Governance Platform v1.2](../release-overview.mdx) — the current release line and its documentation areas
- [Release Manifest](../deployment/release-manifest.mdx) — the chart versions, image tags, and digests a release pins
- [Upgrade](../deployment/upgrade.mdx) — moving an environment to this release
- [Rollback](../deployment/rollback.mdx) — returning to the previous release if the upgrade is not accepted
- [Known Issues](../deployment/known-issues.mdx) — release advisories to review before installing
- [Governance Platform v1.1.1 Release Notes](./v1-1-1.mdx) — the release before this one