Skip to content

fix(authserver,datacustodian): FB=34_35 client access token, CMD v2.14 customer scopes, FB_51 requires customerResourceURI - #260

Open
dfcoffin wants to merge 2 commits into
mainfrom
fix/client-access-token-bulk-scope
Open

dfcoffin wants to merge 2 commits into
mainfrom
fix/client-access-token-bulk-scope

Conversation

@dfcoffin

Copy link
Copy Markdown
Contributor

Aligns the token scopes with ESPI practice as certified in Green Button CMD testing. Follow-up to #258 (#251).

The rules

  • FB=34_35 and FB=36_40 are unique Function Block combinations. They identify the Third Party client access token and the registration access token, and only client_credentials can yield them.
  • Every other FB= scope is a customer access token. It may name only the customer data Function Blocks in the GBA Green Button Data Custodian Connect My Data (CMD) Certification Application v2.14:
    • Energy Usage: FB 1, 3–13, 15–17, 26–29, 31, 35, 37, 39, 40.
    • Retail Customer: FB 51, 53–62, 64, 65, 67, 69–71 (68 is reserved).
  • The client access token is the only Third Party token the DC's ESPI Authorization API accepts, and later the Bulk API (DC: implement ESPI Batch/Bulk API — Third Party client access token only, scoped to its own Authorizations #256).
  • Every access token whose scope includes FB_51 carries customerResourceURI.

Changes

Authorization Server

  • EspiGrantScopePolicy:
    • client_credentials now allows FB=34_35 (CLIENT_ACCESS_TOKEN_SCOPE).
    • Upload_Admin_Access is removed: it belonged to the original GBA Sandbox and is not being migrated.
    • The customer rule is now an allowlist of the CMD v2.14 Function Blocks. It replaces fix(authserver): restrict each OAuth grant to its own kind of scope (#251) #258's ban on FB 36 and FB 40 anywhere in a customer scope. That ban rejected customer scopes that certified Third Parties use: FB 40 appears among the customer FBs at 42 certified utilities. FB=34_35 and FB=36_40 still can never pass, because FB 34 and FB 36 are not customer data Function Blocks.
  • GrantBackchannelTokenCustomizer: an authorization_code token whose granted scope includes FB_51 is issued only if the DC back-channel returns a customerResourceURI. Otherwise the token request fails with server_error, so no token is issued.
  • The client-management scope list and the userinfo rights drop Upload_Admin_Access. The third_party demo client may request FB=34_35. It keeps ThirdParty_Admin_Access for the TP's own actuator.

Data Custodian

Local kit: the TP datacustodian-admin registration requests FB=34_35. The smoke scripts get the client access token with FB=34_35 and check that ThirdParty_Admin_Access is refused by the Authorization API, for 27 checks in total. docs/LOCAL_TESTING.md is updated.

Tests

  • EspiGrantScopePolicyTest covers:
    • real certified customer scopes;
    • FBs outside the CMD v2.14 list (2, 14, 18, 19, 34, 36, 66, 68);
    • FB=34_35 and FB=36_40 in any spelling;
    • Upload_Admin_Access.
  • GrantBackchannelTokenCustomizerTest:
    • FB_51 without customerResourceURI gives server_error and writes no claims;
    • FB_51 with it writes all three claims;
    • FB_51 detection across space-separated scopes.
  • EspiScopeOpaqueTokenIntrospectorTest:
    • client access token mapping;
    • FB=34_35 on a customer token;
    • a customer scope that lists FB 35.
  • AdminRowScopeTest and AuthorizationControllerTest: the client access token passes and is row-scoped; ThirdParty_Admin_Access gets 403.
  • Locally:
    • the AS suite passes without the Testcontainers group;
    • the DC tests above pass;
    • both smoke.sh and smoke.ps1 pass 27/27 against the running AS, DC and TP stack.

🤖 Generated with Claude Code

dfcoffin and others added 2 commits November 15, 2026 00:56
…d to certifiable FBs; FB_51 needs customerResourceURI

- client_credentials may yield the Third Party client access token FB=34_35 (alongside FB=36_40,
  ThirdParty_Admin_Access, DataCustodian_Admin_Access, authserver.admin, client.create).
  Upload_Admin_Access is dropped: it is not migrated from the original GBA Sandbox.
- authorization_code scopes may name only the customer data Function Blocks listed in the GBA CMD
  Certification Application v2.14 (Energy Usage 1-13, 15-17, 26-29, 31, 35, 37, 39, 40; Retail
  Customer 51, 53-62, 64, 65, 67, 69-71). This replaces the {36, 40} individual-FB reservation, which
  rejected certified customer scopes that list FB 40; FB=34_35 and FB=36_40 still never pass.
- A customer token whose scope includes FB_51 is issued only when the Data Custodian returns a
  customerResourceURI; otherwise the token request fails with server_error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orization API

- AS: the third_party demo client may request FB=34_35 (client_credentials); ThirdParty_Admin_Access
  stays for the TP's own actuator.
- DC: EspiScopeOpaqueTokenIntrospector maps an FB=34_35 token whose introspected sub equals its
  client_id (a client_credentials token) to ESPI_CLIENT_ACCESS_TOKEN and no FB_ authorities; FB=34_35
  on any other token grants nothing. The ESPI Authorization API accepts the DataCustodian admin or
  the client access token only (ThirdParty_Admin_Access is now 403), still row-scoped by client_id.
- TP local: datacustodian-admin requests FB=34_35.
- Local kit: smoke scripts get the client access token with FB=34_35 and check that
  ThirdParty_Admin_Access is refused by the Authorization API (27 checks); runbook updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant