Skip to content

v0.17.0

Release Date: 2026-10-18

This release lets relying-party applications manage managed principals (people without an email, such as a child, whose accounts managers control) through SystemAuth, instead of holding SystemAuth's database. It also tightens two defaults: nobody becomes a manager without agreeing, and an application that is not federated refuses contract operations. Both are breaking; see the upgrade notes.

Highlights

  • Managed-principal API on SystemAuth. When managed principals are enabled, SystemAuth built by systemauthsvc serves /managed-principals. A relying party calls it with the signed-in manager's access token, granted systemforge:managed_principals, to create and list managed principals, issue and revoke login tokens, end sessions, list and remove managers, issue and redeem claims, and invite managers. The client is taken from the token and every write is audited when Options.AuditEmitter is set. See Managed Principals.
  • A client for relying parties. identity/managedprincipal/mpclient is a typed Go client over that API, with errors wrapped in *APIError. See Relying Parties.
  • Bearer access with the client. systemauth.Server.BearerAccess and BearerAuthenticator authenticate SystemAuth access tokens and carry the token's client, scopes and token ID, adapted to requestprincipal.
  • Managers join with consent. managedprincipal.Service.Create names only the acting manager, and AddManager is refused; other managers join by accepting an invitation or redeeming a claim. WithDirectManagerAdds keeps direct adds for administrator tooling.
  • Issuing a login token needs manage_credentials, which guardians and educators hold, so an application-defined role cannot issue one.
  • One answer for principals that are not the caller's. The managed-principal handler answers 403 for an unknown or unmanaged principal, as for one the caller does not manage.
  • Contract operations need federation. The contract's identity, policy and audit operations answer 403 until the application is federated, including after it leaves a federation. Meta and health stay open. See Product Contract.

Upgrade notes

  1. Standalone applications that serve the contract API. Identity, policy and audit operations now answer 403 while the application is not federated. Federate the application, or set Config.AllowUnauthenticatedStandalone in development and tests where untrusted callers cannot reach the endpoints.
  2. Code that adds managers directly. Create with managers other than the actor, and AddManager, return ErrConsentRequired. Invite those managers or issue a claim. Administrator tooling and migrations can build the service with managedprincipal.WithDirectManagerAdds().
  3. Custom manager roles. A manager in a role registered with WithRoles can no longer issue login tokens. Issue them as a guardian or educator.
  4. Enabling the API for a relying party. Set managed_principals.enabled for the deployment, managed_principals: true on the application's client, and add systemforge:managed_principals to the client's scopes. The application requests the scope when the manager signs in.
  5. No migration. This release adds no schema changes.

Known limits

  • The API does not attach a verified email to a managed principal: a relying party cannot prove that an address belongs to the principal. It waits for verified email through SystemAuth.
  • Rate-limit storage for the API's code routes is in memory by default; deployments with several instances pass shared storage through Options.ManagedPrincipalRates.
  • Organization management is not served to relying parties; organizations are managed in SystemAuth and reach applications through the orgs claim.