-
Notifications
You must be signed in to change notification settings - Fork 0
Feature/credential selection #423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
67 commits
Select commit
Hold shift + click to select a range
94824ca
feat: implement explicit credential selection in proof controller
rmlearney-digicatapult e4fc1c0
version bump
rmlearney-digicatapult c7b0da4
one-liner
rmlearney-digicatapult 2160443
chore: update integration test instructions to match README
rmlearney-digicatapult e19e478
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 770c1a7
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 938342c
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 1d625be
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 5ef7855
Update README.md
rmlearney-digicatapult b805fd3
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 568a7e1
fix: enhance proof controller validation, logging and tests
rmlearney-digicatapult ae33840
refactor: secure logging and remove unused endpoint
rmlearney-digicatapult c298134
install latest versions of npm in dockerfile
rmlearney-digicatapult f10d2ef
Update src/controllers/v1/proofs/ProofController.ts
rmlearney-digicatapult 6ef2729
Update docs/explicit-credential-selection.md
rmlearney-digicatapult 4015034
Update package.json
rmlearney-digicatapult 2dd1365
version bump
rmlearney-digicatapult bc56fbf
refactor(proofs): optimize validation and redaction in acceptRequest
rmlearney-digicatapult cccac33
refactor(proofs): remove any type usage in acceptRequest
rmlearney-digicatapult 79b5f9b
feat(scripts): add credential existence check to maker-accept-proof-f…
rmlearney-digicatapult b38c402
fix: relax AcceptProofProposalOptions validation for TSOA
rmlearney-digicatapult 63961f1
fix(proofs): address PR review comments
rmlearney-digicatapult 45a250d
fix: consolidate logging and add revealed status test
rmlearney-digicatapult 133439a
test: verify acceptProofStub is not called in validation tests
rmlearney-digicatapult 5ed1727
remove npm install
rmlearney-digicatapult 8760b50
simplify validation logic
rmlearney-digicatapult 0802f08
address test review
rmlearney-digicatapult 2c14804
address readme comment
rmlearney-digicatapult 54fc5ce
feat: enrich proof webhook with proposal message and add getProposalM…
rmlearney-digicatapult 2446432
comment
rmlearney-digicatapult 5e6984b
rename anoncreds variables
rmlearney-digicatapult 7de8734
commented code
rmlearney-digicatapult 71b09a2
only metadata logging at info level
rmlearney-digicatapult 8d619d3
revert event handler and webhook test changes
rmlearney-digicatapult cc504d2
comment
rmlearney-digicatapult 693daf1
improve proofcontroller tests
rmlearney-digicatapult 1148f03
feat: enforce strict attribute disclosure validation in proof acceptance
rmlearney-digicatapult 46d24e9
fix test expectation text
rmlearney-digicatapult c2e1302
refactor(proofs): separate proof content from record endpoint
rmlearney-digicatapult a882a3e
Merge branch 'main' into feature/credential-selection
rmlearney-digicatapult 4585917
Merge main into feature/credential-selection: keep v0.17.0 but accept…
rmlearney-digicatapult 66c3a56
Refactor ProofController, improve types, and add webhook noise reduction
rmlearney-digicatapult 18c194d
Update explicit credential selection docs with new endpoints
rmlearney-digicatapult 622650c
feat: enhance proof controller error messages and update tests for ex…
rmlearney-digicatapult 8eafe6a
linting
rmlearney-digicatapult b18ae55
docker-compose-testnet one liner
rmlearney-digicatapult 0a0c0b9
fix: resolve integration test failures and 500 error in ProofController
rmlearney-digicatapult 3a43b83
docs: add client-side helper example for credential selection
rmlearney-digicatapult 9c44a87
change log levels
rmlearney-digicatapult c74456d
improve documentation
rmlearney-digicatapult 8a98f33
fix(test): correct getCredentialsForRequest mock structure in proof u…
rmlearney-digicatapult a6920ad
linting
rmlearney-digicatapult c3c83e5
fix(test): add polling and increase timeout for flaky proof verificat…
rmlearney-digicatapult 881e2d6
increase timeout for flaky IPFS test
rmlearney-digicatapult 08e43b7
Merge branch 'main' into feature/credential-selection
rmlearney-digicatapult 524d998
refactor(scripts): make CLI parameters optional and improve workflow …
rmlearney-digicatapult f168f01
renames
rmlearney-digicatapult b8c69bf
remove script dependency from e2e test
rmlearney-digicatapult 6e5aa37
feat: add endpoint to retrieve matching credentials for proof request
rmlearney-digicatapult a4f99a4
open IPFS gateway port for integration test runner
rmlearney-digicatapult 1fbfafe
Merge branch 'main' into feature/credential-selection
rmlearney-digicatapult 07baa87
unit test new endpoint
rmlearney-digicatapult 4fd3fdf
remove unnecessary
rmlearney-digicatapult 1149531
e2e test now uses new endpoint
rmlearney-digicatapult cf57e29
Merge branch 'main' into feature/credential-selection
rmlearney-digicatapult 05b5ceb
remove test expectation
rmlearney-digicatapult 4f84d22
remove ipfs gateway from integration test
rmlearney-digicatapult File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| # Explicit Credential Selection | ||
|
|
||
| When responding to a Proof Request, an agent may hold multiple credentials that satisfy the request's requirements (e.g., multiple credentials from the same issuer, or multiple credentials with the same attribute names). By default, the agent might select any valid credential, which can lead to incorrect data being shared if a specific credential was intended. | ||
|
|
||
| The **Explicit Credential Selection** feature allows a client (controller) to specify exactly which credential ID should be used for each requested attribute or predicate. | ||
|
|
||
| ## The Problem | ||
|
|
||
| 1. **Ambiguity**: If a user has two "Employee ID" credentials, the agent doesn't know which one to present. | ||
| 2. **Complexity**: The underlying Credo-TS `acceptRequest` method requires a highly complex `proofFormats` object containing deep metadata (`schemaId`, `credDefId`, `revocationRegistryId`, raw values, etc.) to specify a credential. Constructing this object on the client side is difficult and error-prone. | ||
|
|
||
| ## The Solution: Simplified Proof Formats | ||
|
|
||
| The `veritable-cloudagent` API supports a **Simplified Proof Format**. Clients can provide a lightweight object specifying only the `credentialId` and `revealed` status for each attribute. The agent's controller then "hydrates" this object by fetching the full credential details from the wallet before passing it to the core agent. | ||
|
|
||
| ### API Usage | ||
|
|
||
| **Endpoint**: `POST /v1/proofs/{proofRecordId}/accept-request` | ||
|
|
||
| **Body**: | ||
|
|
||
| ```json | ||
| { | ||
| "autoAcceptProof": "contentApproved", | ||
| "proofFormats": { | ||
| "anoncreds": { | ||
| "attributes": { | ||
| "attribute_name_1": { | ||
| "credentialId": "credential-uuid-1", | ||
| "revealed": true | ||
| }, | ||
| "attribute_name_2": { | ||
| "credentialId": "credential-uuid-1", | ||
| "revealed": true | ||
| } | ||
| }, | ||
| "predicates": { | ||
| "predicate_name_1": { | ||
| "credentialId": "credential-uuid-2" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ### How it Works | ||
|
|
||
| The `ProofController` employs a three-path logic flow to handle proof acceptance: | ||
|
|
||
| 1. **Auto-Selection (No `proofFormats` provided)** | ||
| * If the client omits `proofFormats`, the agent automatically selects the best available credentials that satisfy the request. | ||
| * This is useful for simple use cases where ambiguity is not a concern. | ||
|
|
||
| 2. **Hydration (Simplified `proofFormats` provided)** | ||
| * The controller detects the simplified format (missing `credentialInfo`). | ||
| * It queries the agent for all valid credentials for this proof request. | ||
| * It matches the `credentialId` provided by the client with the available credentials. | ||
| * It populates the required `credentialInfo` (Schema ID, Cred Def ID, etc.) into the request object. | ||
| * **Validation**: | ||
| * If attributes are missing in the simplified format, the API returns a `400 Bad Request`. | ||
| * If no matching credentials are found to satisfy the request, the API returns a `404 Not Found`. | ||
|
|
||
| 3. **Pass-Through (Full `proofFormats` provided)** | ||
| * If the client provides the full, complex Credo-TS proof format, the controller passes it directly to the agent. | ||
| * This supports advanced use cases where the client needs full control over the cryptographic metadata. | ||
|
|
||
| ### Example Scenario | ||
|
|
||
| **Scenario**: A Manufacturer (Bob) needs to prove the `tdp_reference` of a specific product to an OEM (Charlie). Bob has multiple credentials for different products. | ||
|
|
||
| 1. **Charlie** sends a Proof Request for `tdp_reference`. | ||
| 2. **Bob's Client** inspects the request and identifies that `credential-123` contains the correct TDP reference. | ||
| 3. **Bob's Client** calls `accept-request` with: | ||
|
|
||
| ```json | ||
| { | ||
| "proofFormats": { | ||
| "anoncreds": { | ||
| "attributes": { | ||
| "tdp_reference": { | ||
| "credentialId": "credential-123", | ||
| "revealed": true | ||
| } | ||
| }, | ||
| "predicates": {} | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| 4. **Bob's Agent** looks up `credential-123`, retrieves its full metadata, and generates a proof using that specific credential. | ||
|
|
||
| ## Retrieving Proof Context | ||
|
|
||
| To construct the `accept-request` body, the client often needs to know what attributes are being requested and what credentials are available. | ||
|
|
||
| ### 1. Get Proof Record with Content | ||
|
|
||
| To avoid making multiple calls, you can fetch the proof record along with its content (request and presentation data) in a single request. | ||
|
|
||
| **Endpoint**: `GET /v1/proofs/{proofRecordId}?includeContent=true` | ||
|
|
||
| **Response**: | ||
| Returns the `ProofExchangeRecord` with an additional `content` property containing the raw proof format data. | ||
|
|
||
| ### 2. Get Simplified Proof Content | ||
|
|
||
| The raw proof content can be complex to parse. You can request a simplified view that flattens the structure into simple key-value pairs. | ||
|
|
||
| **Endpoint**: `GET /v1/proofs/{proofRecordId}/content?view=simplified` | ||
|
|
||
| **Response**: | ||
|
|
||
| ```json | ||
| { | ||
| "attribute_name_1": "value_1", | ||
| "attribute_name_2": "value_2" | ||
| } | ||
| ``` | ||
|
|
||
| This is particularly useful for displaying the values of a received proof (Verifier role) or understanding what is being requested (Prover role) without navigating the deep AnonCreds structure. | ||
|
|
||
| ## Developer Experience | ||
|
|
||
| While the simplified format is much cleaner than the raw format, constructing the nested JSON object can still be verbose. It is recommended to use a helper function in your client application to generate this structure. | ||
|
|
||
| ### Client-Side Helper Example (TypeScript) | ||
|
|
||
| > **Important**: The `credentialId` used in the selection payload must be the **Wallet Credential ID** (the ID of the credential stored in the wallet), NOT the **Credential Exchange Record ID** (the ID of the record tracking the issuance process). | ||
| > | ||
| > In Credo-TS, you can access this via `credentialRecord.credentials[0].credentialRecordId`. | ||
|
|
||
| ```typescript | ||
| /** | ||
| * Helper to construct the simplified proof format payload. | ||
| * | ||
| * @param selections A map where the key is the attribute name and the value is the credential ID to use. | ||
| * @returns The formatted payload ready for the API. | ||
| */ | ||
| function createSelection(selections: Record<string, string>) { | ||
| const attributes: Record<string, { credentialId: string; revealed: boolean }> = {}; | ||
|
|
||
| for (const [key, credId] of Object.entries(selections)) { | ||
| attributes[key] = { credentialId: credId, revealed: true }; | ||
| } | ||
|
|
||
| return { | ||
| proofFormats: { | ||
| anoncreds: { | ||
| attributes | ||
| } | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| // Usage Example: | ||
| // 1. User selects specific credentials for the requested attributes | ||
| const userSelections = { | ||
| 'name': 'credential-uuid-123', | ||
| 'email': 'credential-uuid-456' | ||
| }; | ||
|
|
||
| // 2. Generate the payload | ||
| const payload = createSelection(userSelections); | ||
|
|
||
| // 3. Send to API | ||
| await client.acceptProofRequest(proofRecordId, payload); | ||
| ``` | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Empty file.
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.