Upgrade Guide

This guide covers user-visible migration steps between MCP Hangar releases.

Upgrade to 1.4.0

MCP Hangar 1.4.0 builds on the 1.3 front-door release. It adds tenant-scoped digest pins, multi-issuer OIDC trust, resource-bound JWT audiences, and per-tenant canary routing for MCP server groups.

Review OIDC audience binding

If auth.oidc.resource_uri is set, it now becomes the expected JWT aud value for every trusted issuer. This aligns token validation with the RFC 9728 Protected Resource Metadata resource value and RFC 8707 resource indicators.

Before upgrading production front-door deployments:

  • Confirm the authorization server issues tokens with aud equal to auth.oidc.resource_uri.
  • If you need legacy audience values per issuer, leave resource_uri unset and configure audience on each issuer instead.
  • Prefer setting resource_uri behind proxies; otherwise Hangar derives the resource from the incoming request scheme and host.

Move multi-issuer deployments to auth.oidc.issuers

Single-issuer config still works:

auth:
  oidc:
    enabled: true
    issuer: https://issuer-a.example.com
    audience: mcp-hangar

Use auth.oidc.issuers when one Hangar instance trusts multiple authorization servers:

auth:
  oidc:
    enabled: true
    resource_uri: https://hangar.example.com
    tenant_claim: tenant_id
    issuers:
      - issuer: https://issuer-a.example.com
        audience: https://hangar.example.com
        jwks_uri: https://issuer-a.example.com/jwks
      - issuer: https://issuer-b.example.com
        audience: https://hangar.example.com
        jwks_uri: https://issuer-b.example.com/jwks
        groups_claim: roles

Tokens with a missing, empty, non-string, or untrusted iss claim now fail closed with a 401 instead of reaching any issuer validator.

Add tenant-scoped digest pins intentionally

1.4.0 can enforce schema pins per tenant on the live invocation path:

mcp_servers:
  payments:
    mode: remote
    endpoint: https://payments.example.com/mcp
    tool_projection:
      digest_enforcement: block
      tenant_overrides:
        "tenant:a":
          pins:
            refund: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

digest_enforcement is scoped per MCP server. If unset, pin mismatches default to block. Roll out pins with audit or warn first when you are recomputing digests or onboarding a new tenant.

The deprecated allow_degraded unknown-tool policy is still accepted with a DeprecationWarning in 1.4.0, but allow_unverified remains the canonical value. Do not add new allow_degraded config.

Gate canary routing by tenant identity

Group canary routing only applies when Hangar has a tenant_id for the caller. Explicit tenant pins win first, then the sticky percentage split, then the regular load-balancing strategy.

mcp_servers:
  search:
    mode: group
    strategy: weighted_round_robin
    canary:
      member: search-v2
      split_pct: 10
      pinned_tenants:
        "tenant:beta": search-v2
    members:
      - id: search-v1
        mode: remote
        endpoint: https://search-v1.example.com/mcp
      - id: search-v2
        mode: remote
        endpoint: https://search-v2.example.com/mcp

Invalid canary targets are skipped with a warning. If a pinned or canary member is not in rotation, Hangar falls back to the group load balancer instead of routing traffic to an unhealthy member.

Upgrade to 1.3.0

MCP Hangar 1.3.0 relicenses the project to MIT, folds the former enterprise package into the main mcp_hangar package, and tightens digest-pinning canonicalization.

Recompute pinned tool digests

compute_tool_digest() now uses RFC 8785 JSON Canonicalization Scheme (JCS) instead of json.dumps output. Existing pinned digests produced by earlier versions may no longer match and must be regenerated before enforcement mode is enabled.

When recomputing digests, note the v1.3 normalization rules:

  • None, {}, [], and "" are treated as absent values.
  • Tool entries with a missing, empty, or non-string name field are rejected.

Recommended rollout:

  1. Upgrade one environment with digest enforcement set to audit or warn.
  2. Collect the new expected digests from the audited tool inventory.
  3. Replace old pins with the RFC 8785/JCS digests.
  4. Re-enable block only after the audited drift is resolved.

Rename ALLOW_DEGRADED to ALLOW_UNVERIFIED

DigestUnknownPolicy.ALLOW_DEGRADED was renamed to DigestUnknownPolicy.ALLOW_UNVERIFIED for clarity.

If your YAML or code uses the string value allow_degraded, change it to allow_unverified. MCP Hangar 1.3 still accepts allow_degraded with a DeprecationWarning; 1.4.0 still accepts the alias, but new configuration should use only allow_unverified.

Remove license-tier assumptions

The former BSL/enterprise split is gone. All MCP Hangar features are now available under the MIT license.

Required cleanup for integrations and deployment manifests:

  • Stop setting HANGAR_LICENSE_KEY; v1.3 ignores it and emits a DeprecationWarning when present.
  • Remove checks for LicenseTier, LicenseValidation, or ApplicationContext.license_tier.
  • Update imports that referenced the former enterprise/ package; auth, compliance, approvals, integrations, and persistence modules now live under src/mcp_hangar/.

Verify interceptor discovery clients

interceptors/list now returns unique instance names required by SEP-1763:

  • mcp-hangar-validator
  • mcp-hangar-mutator

If a client keyed both entries by the previous shared name mcp-hangar, update it to handle the two explicit instance names.