feat: offer credentials to every member over DCP - #34
Merged
Merged
Conversation
A member's credentials no longer depend on where it runs: the hub has the IssuerService send it a DCP credential offer, and the member's own IdentityHub requests them. CFM's onboarding activity, which requested them during provisioning, leaves the orchestration together with the offboarding activity that revoked them — so the path a system under test takes is the one every member takes, and every managed run exercises it. Hosting follows from the identity instead of a flag: a member that supplies a did runs elsewhere and nothing is provisioned for it; one that omits it gets a did minted here and its EDC resources deployed. externallyHosted is gone from the hub's API, domain, entity mapping and the verification UI's model; the column stays in existing databases, unused. Since provisioning no longer ends with issued credentials, the hub waits for the participant context before offering (participant.provisioning.*), every membership ends at CREDENTIALS_OFFERED, and consumers wait for the delivery: the managed run gains an AWAIT_CREDENTIALS step, ensuring the verification participant waits for its own credentials, and the e2e suite waits for the terminal state. Offboarding no longer revokes credentials — documented in the README and the seed job, to be re-added through the IssuerService admin API whenever offboarding becomes a real flow. Verified live: verification participant holds three credentials, one each; managed and external runs and the hub e2e suite green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1jpMYKYNxy49ZY3CcEn5M
wolf4ood
approved these changes
Sep 18, 2026
The Onboarding API now owns both halves of the issuer relationship: it registers the credential holder and then has the IssuerService send the DCP offer. The hub therefore DEPLOYS a member it hosts first and REGISTERS it second — the offer is pushed to the credential service the member's DID document advertises, so the wallet has to exist by then. - onboarding-api: CredentialOfferService port + IssuerService adapter; WALLET_PROVISIONED -> CREDENTIALS_ISSUED -> COMPLETED. - membership-hub: PROVISIONING -> PROVISIONED -> SUBMITTED -> CREDENTIALS_OFFERED, the confirmation being the terminal success; POST /api/members refuses a DID or BPN a live membership holds (409) before anything is deployed; the issuer client, its config and the sudo jwtlet mapping are gone. - verification-ui: awaitProvisioned waits for the participant context AND the onboarding process id, which now arrives after provisioning. - docs: the new order, and the orphaned-resources gap a registration declined after deployment leaves behind. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1jpMYKYNxy49ZY3CcEn5M
The class the previous commit's test changes reference: deploys a tenant and a participant profile through the CFM Tenant Manager and waits for the participant context, so the OSP contract test registers a partner whose wallet exists — which the credential offer inside the registration is pushed to. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01K1jpMYKYNxy49ZY3CcEn5M
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every member now gets its credentials the same way: the hub has the IssuerService send a DCP offer, and the member's own wallet requests them. The path a system under test takes is the one the VE takes for its own participants, so every managed run exercises it.
didand nothing is provisioned for you; omit it and the hub mints one and deploys your EDC resources.externallyHostedis gone from API, domain, persistence and UI.participant.provisioning.*); every membership ends atCREDENTIALS_OFFERED.AWAIT_CREDENTIALSstep, ensuring the verification participant waits for its own credentials, and the e2e suite waits for the terminal state.The Onboarding API is untouched; it still registers the holder, which is what makes the offer possible.
Verified live: verification participant holds three credentials, one each; managed run, external run against the vendor stack, and the hub e2e suite all green.
🤖 Generated with Claude Code