Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions packages/vc-delegation-engine/DELEGATION_REFERENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Delegation Reference

Reference notes for `@docknetwork/vc-delegation-engine`, based on current implementation and tests.

## Processing Model

`verifyVPWithDelegation` runs in this order:

1. Parse the expanded VP and extract signer (`proof.verificationMethod`).
2. Ingest `verifiableCredential` entries:
- Expanded JSON-LD credentials are compacted using `credentialContexts`.
- VC-JWT with JSON-LD context is expanded and treated the same way.
- VC-JWT without JSON-LD context is skipped from chain logic and returned in `skippedCredentials`.
3. Validate delegation references:
- `previousCredentialId` must resolve if present.
- Any `DelegationCredential` must include a valid `rootCredentialId`.
4. Build chains tail-first (`previousCredentialId` links), reject cycles, then evaluate each chain.
5. Optionally resolve and verify delegation policy (id + digest + semantic checks).
6. Run Rify inference, derive authorized claims, and build Cedar-ready `facts`/`entities`.
7. Return `allow` on success, `deny` with typed failure codes on error.

## Behavioral Guarantees

- Fail-closed: errors become `decision: "deny"` with stable `DelegationErrorCodes`.
- Credential array order is not trusted; chains are reconstructed from references.
- Root and previous references are bundle-contained (no implicit external chain lookup).
- Policy checks are digest-bound (`delegationPolicyDigest` must match fetched document hash).
- Policy chain checks enforce:
- role ancestry (and optional `cannotDelegateToSameRole`),
- max delegation depth,
- parent/child expiration ordering,
- capability/claim monotonic narrowing.
- Unauthorized claims can be made fatal with `failOnUnauthorizedClaims: true`.
- Parent claim hierarchy is exposed as nested `parentClaims` in evaluation outputs.
- Presentations without delegation links are still supported and evaluated.

## Practical References

### Examples

- `examples/simple-delegation.js` - minimal allow/deny delegation flow.
- `examples/delegation-chain.js` - multi-hop credit-score delegation.
- `examples/multi-delegation-vp.js` - one VP containing multiple tails/chains.
- `examples/pharmacy.js` - role/capability policy scenario using pharmacy fixtures.
- `examples/document-loader.js` - JSON-LD loader with policy-document resolution.

### Fixtures

- `tests/fixtures/delegation-pharmacy-policy.json`
- `tests/fixtures/policy-integration-pharmacy.json`
- `tests/fixtures/policy-integration-travel.json`
- `tests/fixtures/simpleDelegation.js`
- `tests/fixtures/multiDelegation.js`
- `tests/fixtures/staff.js`
- `tests/fixtures/pharmacy.js`
- `tests/fixtures/nonDelegated.js`

### High-signal tests

- `tests/unit/engine.test.js` - chain reconstruction, reference errors, parentClaims shaping.
- `tests/unit/delegation-policy.test.js` - digest, semantics, roles, lifetime, and narrowing checks.
- `tests/unit/jwt-engine.test.js` - JSON-LD vs non-JSON-LD VC-JWT handling and skip behavior.
- `tests/examples.test.js` - fixture-backed end-to-end behavior.

## Change Checklist

When delegation behavior changes:

- update this file in the same PR,
- update/add examples for new patterns,
- update fixtures for new chain shapes,
- add tests for both allow and deny paths.
24 changes: 24 additions & 0 deletions packages/vc-delegation-engine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@ yarn add @docknetwork/vc-delegation-engine

- **Errors, Summaries, and Constants**: `DelegationError`/`DelegationErrorCodes` offer structured failures, while `summarize.js` and `constants.js` capture reusable IRIs, action IDs, and summary builders for every delegation evaluation.

## Delegation Architecture Notes

The engine behavior includes several decisions that are important for integrators but easy to miss when reading only API signatures:

- **Fail-closed verification**: any structural, policy, digest, or inference failure yields a `deny` decision with typed failure codes.
- **Tail-first chain reconstruction**: chains are built from each tail credential by following `previousCredentialId`, and they reject cycles and missing links.
- **Strict root anchoring**: delegation credentials must carry `rootCredentialId`; the root must be present in the same presentation bundle.
- **Policy integrity binding**: when policy checks are enabled and a root references `delegationPolicyId`/`delegationPolicyDigest`, a `documentLoader` must fetch the policy and the digest must match.
- **Monotonic narrowing model**: child credentials are validated as same-or-narrower than parent grants (roles, capabilities, and expiration windows).
- **Signer-as-principal model**: the VP proof signer is surfaced as principal/context input for Cedar decisions.
- **Dual-path VC-JWT ingestion**: JSON-LD VC-JWTs are expanded and evaluated as chains; VC-JWTs without JSON-LD context are intentionally skipped from chain logic but exposed as `skippedCredentials` for policy use.

For a fuller record, see the consolidated delegation reference: [`DELEGATION_REFERENCE.md`](./DELEGATION_REFERENCE.md).

## Working Material (Non-normative)

Some delegation material is intentionally preserved as working references rather than normative docs:

- scenario-heavy examples that encode practical policy patterns
- test fixtures that capture edge cases and expected failures
- policy JSON fixtures that act as reference schemas for role/capability narrowing

See [`DELEGATION_REFERENCE.md`](./DELEGATION_REFERENCE.md) for the curated index and contributor checklist.

## License

This SDK is licensed under the MIT License. See the [LICENSE.md](../../LICENSE.md) file for more details.
Expand Down
Loading