Skip to content

feat: offer credentials to every member over DCP - #34

Merged
paullatzelsperger merged 4 commits into
mainfrom
feat/unified-credential-offer
Sep 18, 2026
Merged

paullatzelsperger merged 4 commits into
mainfrom
feat/unified-credential-offer

Conversation

@paullatzelsperger

@paullatzelsperger paullatzelsperger commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

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.

  • Orchestration: CFM's onboarding activity (requested credentials during provisioning) and the offboarding activity (revoked them) leave the DAG.
  • Hosting follows the identity, not a flag: supply a did and nothing is provisioned for you; omit it and the hub mints one and deploys your EDC resources. externallyHosted is gone from API, domain, persistence and UI.
  • States: the hub waits for the participant context before offering (participant.provisioning.*); every membership ends at CREDENTIALS_OFFERED.
  • Waiting for 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.
  • Known gap: offboarding no longer revokes credentials (documented in the README and the seed job).

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

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
paullatzelsperger and others added 3 commits September 18, 2026 11:10
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
@paullatzelsperger
paullatzelsperger merged commit 271fb99 into main Sep 18, 2026
2 checks passed
@paullatzelsperger
paullatzelsperger deleted the feat/unified-credential-offer branch September 18, 2026 10:12
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.

2 participants