Skip to content

Migrate existing service-token consumers to the generic application service-access model #880

Description

@NateIsern

Reconciliation — 2026-10-05

The generic resource/grant cutover remains pending. Fresh source review of Moovo main cc617 auth still finds SERVICE_SECRET creating a synthetic system user / internal application in authenticateTokenOrApiKey. This is retained active source, not evidence that it ran in production. Do not infer its removal, generic Console grants or a Mercaria→Moovo resource-audience canary from shared SDK adoption. The original criteria remain open; old dated headers below are historical.


Status 2026-09-30 (audited against main f345d27)
Blocked on #875-#879. Already done: HMAC removal (#877/ADR 0012), so the HMAC/shared-signing-secret inventory is moot; legacy #195/#213/#215 are closed. Still live: Moovo middleware/auth.ts:101-107 (SERVICE_SECRET, system user, appId: 'internal') and Mercaria waiting on #878. Drop "environment-aware flags" and "dual authority/rollback": clean cut, no config switches.


Part of #873. Depends on #875 through #879. This issue owns compatibility, seeding, documentation reconciliation and removal of Oxy-side special cases; consumer-repository shared secrets are removed in their own linked issues.

Goal

Move current Oxy service-token behavior and official application integrations onto the generic resource/grant/audience model without creating duplicate Applications, silently widening authority or keeping permanent parallel authorization systems.

Inventory

Create a verified inventory of:

  1. Applications with service credentials.
  2. Credential environments and requested scopes.
  3. Routes using service-token middleware.
  4. Tokens currently minted for aud: oxy-api.
  5. Oxy Pay's hardcoded service-credential and Console scope behavior.
  6. Shared signing secrets distributed to consumers.
  7. Consumer-local SERVICE_SECRET, API key or synthetic-principal paths.
  8. Documentation and examples that describe obsolete token claims, rotation grace, signing or delegation behavior.
  9. Official application seed records for Mercaria, Moovo and other products.
  10. Runtime metrics needed to know when compatibility can be removed.

Do not infer active use only from code references. Use credential last-use and safe request metrics where available.

Canonical application seeding

  1. Preserve the existing Mercaria, Moovo, Oxy Pay and other Application ids.
  2. Extend the official seed/reconcile system with resource API definitions and grants, not duplicate app rows.
  3. Seed development/staging/production separately and only where explicitly approved.
  4. Add the Moovo resource API definition idempotently.
  5. Add the Mercaria to Moovo grant only after the exact scope set and environments are approved.
  6. Add the Moovo to Mercaria event-delivery grant only if the final event architecture requires direct callback access.
  7. Re-running the seed must not revoke unrelated valid grants or credential bindings.
  8. Renames use the existing legacy-name reconciliation rather than generating another identity.

Oxy Pay migration

  1. Represent Oxy Pay as a resource application API under Model resource service APIs and application-to-application grants #875.
  2. Backfill current eligible applications and credentials into explicit grants/bindings.
  3. Preserve current functional access during a bounded migration.
  4. Change Console to the generic service-access UI from Add generic application service access management to Oxy Console #879.
  5. Remove the payments-only token-mint carve-out only when all affected consumers use the new model or replace it with the exact generic policy chosen by ADR: define canonical application principals, resource audiences and service grants #874.
  6. Do not broaden third-party service-token authority during migration.
  7. Add reconciliation proving old and new effective permissions match before cutover.

Documentation reconciliation

Create one canonical service-auth guide and update/remove conflicting copies.

It must accurately document:

  1. Application versus credential versus grant.
  2. One-time secret reveal and hash storage.
  3. Audience/resource-bound token request.
  4. Environment isolation.
  5. Effective scopes.
  6. Asymmetric signing and JWKS.
  7. Resource-server middleware.
  8. User delegation as a separate mechanism.
  9. Rotation grace and revocation behavior.
  10. Mercaria to Moovo example.
  11. Prohibited shared-secret and body-supplied application-id shortcuts.

Generated/package docs must point to the same contract and tests must catch contradictory security claims where practical.

Compatibility rollout

  1. Introduce new token/grant paths behind environment-aware flags.
  2. Upgrade Oxy API first, then one internal resource-server canary.
  3. Upgrade Mercaria and Moovo through their linked epics.
  4. Observe wrong-audience, insufficient-scope, JWKS and token-refresh failures.
  5. Stop issuing legacy tokens for migrated credentials.
  6. Remove old Oxy Pay special cases.
  7. Remove HMAC verification after Move Oxy service tokens to asymmetric signing and JWKS verification #877's bounded window.
  8. Retire obsolete SDK overloads and examples.
  9. Keep a tested rollback that does not recreate indefinite dual authority.
  10. Preserve audit and historical credential records.

Legacy issue reconciliation

Review existing broad application/credential issues such as #213, #215 and #195 against the current Postgres implementation. Close, narrow or cross-link them based on verified remaining work rather than duplicating completed requirements into this epic.

Acceptance criteria

  1. Existing official Application ids survive unchanged.
  2. Oxy Pay and Moovo use the same generic resource/grant model.
  3. The Mercaria to Moovo production relationship is represented by grants and credentials visible in Console.
  4. No current consumer loses access silently during migration.
  5. Legacy and new effective permissions are reconciled before each cutover.
  6. Canonical docs match the actual token, key, grant and rotation implementation.
  7. Old token issuance, hardcoded Console permission UI and Oxy-side shared-signing-secret assumptions have dated removal points.
  8. Consumer repositories can remove synthetic SERVICE_SECRET principals after adopting Add audience-aware service clients and resource-server auth to @oxy.so/core #878.
  9. Rollback preserves existing service availability without reintroducing duplicate application identities.

Activity

  1. NateIsern commented on Aug 8, 2026

    @NateIsern
    MemberAuthor

    Concrete first migration cohort

    Use these linked implementations as the first migration cohort and compatibility proof:

    1. OxyHQ/Moovo#27/#28 adopt the shared resource-server auth and expose the Moovo API.
    2. OxyHQ/Mercaria#156 adopts the shared audience-aware outbound client.
    3. OxyHQ/Moovo#32 and OxyHQ/Mercaria#164 remove their copied SERVICE_SECRET, synthetic system user and appId: internal paths.
    4. OxyHQ/Moovo#29 and OxyHQ/Mercaria#158 prove application-scoped durable event delivery.

    Do not remove compatibility in Oxy until the canary traffic, credential rotation, grant revocation, wrong-audience refusal and rollback paths are measured end to end.

  2. NateIsern commented on Aug 8, 2026

    @NateIsern
    MemberAuthor

    Verified legacy issue state

    The referenced foundations #195, #213 and #215 are already closed as completed. Treat their implemented Application, ApplicationCredential and service-auth error guarantees as the migration baseline.

    Do not reopen or recreate those models. This issue should audit current production behavior, preserve existing ids/credential lifecycle and add only the resource API, grant, audience, JWKS, generic Console and consumer-migration layers defined by #873 through #879.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions