Skip to content

feat: SimpulseID credentials — schema-first domain layer on harbour-credentials#24

Open
jdsika wants to merge 84 commits intomainfrom
feat/gx-compliance-nested
Open

feat: SimpulseID credentials — schema-first domain layer on harbour-credentials#24
jdsika wants to merge 84 commits intomainfrom
feat/gx-compliance-nested

Conversation

@jdsika
Copy link
Collaborator

@jdsika jdsika commented Nov 27, 2025

Summary

This branch builds the schema-first SimpulseID credentials repository on top of harbour-credentials. Relative to main, it adds the LinkML schemas, generation pipeline, examples, manifests, docs, tests, and CI for the SimpulseID credential set.

The latest follow-up pushed on top of the existing branch now also:

  • replaces legacy hyphenated make aliases with grouped command centers such as make test help, make validate help, and make story help
  • adds src/verify_signed_examples.py and wires the SimpulseID storyline to verify the signed JWT / VP artifacts written into the ignored examples/signed/ folder
  • updates root CI and release workflows to the grouped make-command surface so they no longer call removed targets like make install-dev
  • bumps submodules/harbour-credentials to green commit d343dda, which includes the grouped Harbour workflow surface, signed-example verification, the merged OMB baseline at 15bf33a, and the Harbour CI fix for grouped commands

Actual branch diff vs main

Shortstat: 89 files changed, 8,473 insertions, 797 deletions.

Repository / build / CI scaffolding

  • add the core repository scaffolding for generation, validation, tests, docs, and manifests:
    • Makefile
    • pyproject.toml
    • mkdocs.yml
    • GitHub workflows and hook configuration
    • AGENTS.md, CLAUDE.md, and repository workflow docs
  • update CI / release automation to the grouped make surface (make install dev, grouped validation / story commands)

SimpulseID LinkML schemas and generation

  • add the SimpulseID LinkML schemas and import map:
    • linkml/simpulseid.yaml
    • linkml/simpulseid-credentials.yaml
    • linkml/importmap.json
  • wire the root repository to generate its own artifacts while depending on the Harbour schema stack beneath it
  • keep schema.org usage aligned on the https://schema.org/ / sdo: path in the source modelling and docs

Examples, DID documents, and signing flow

  • add the five SimpulseID credential examples under examples/
  • add the full did:ethr example set under examples/did-ethr/
  • keep the current Base resolver storyline consistent across the examples:
    • participants and users expose local P-256 #controller methods
    • optional extra signer keys appear as #delegate-N
    • program and infrastructure-service DIDs use the root DID Core controller property instead of inventing local signing keys
  • update src/sign_examples.py so JWT headers point at the #controller kids used by the issuer DID documents
  • add src/verify_signed_examples.py so make story simpulseid verifies the signed artifacts it writes under examples/signed/

Documentation / manifests / tests

  • add project docs across docs/credentials/, docs/reference/, docs/integration/, docs/getting-started/, and docs/did-methods.md
  • add the local did:ethr reference copy and example storyline docs
  • add wallet manifests under manifests/
  • add SHACL, integrity, and evidence-proof tests under tests/
  • update README and operator docs to match the grouped command centers and ignored signed output folders

Harbour submodule integration

  • update submodules/harbour-credentials to validated commit d343dda
  • this pulls in the merged OMB validator fixes plus Harbour’s explicit JsonWebKey modelling and grouped workflow surface so the root validation flow can discover all referenced schemas and accept the P-256 controller methods in the DID fixtures

Verification

  • make install dev
  • make test
    • Harbour submodule tests: 240 passed
    • Root tests: 62 passed, 7 skipped
  • make story
    • Harbour signed outputs verified:
      • 2 credential JWTs, 2 evidence VP JWTs, and 2 nested VC JWTs in submodules/harbour-credentials/examples/signed/
      • 4 credential JWTs, 3 evidence VP JWTs, and 3 nested VC JWTs in submodules/harbour-credentials/examples/gaiax/signed/
    • SimpulseID signed outputs verified:
      • 5 credential JWTs and 5 evidence VP JWTs in examples/signed/
    • SHACL validation passed for Harbour and SimpulseID
    • final status: OK: Full repository storyline complete

Target branch

  • main

jdsika and others added 25 commits July 2, 2025 08:55
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: jdsika <carlo.van-driesten@bmw.de>
Signed-off-by: felix hoops <9974641+jfelixh@users.noreply.github.com>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: felix hoops <9974641+jfelixh@users.noreply.github.com>
Signed-off-by: felix hoops <9974641+jfelixh@users.noreply.github.com>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
jdsika and others added 8 commits January 22, 2026 22:29
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
- Normalize IRI generation and remove did: prefix to avoid double-# IRIs
- Replace participant inheritance with legalPerson composition
- Fix membership credentials: use member and unique subject URNs
- Strip credentialSubject from evidence snippets
- Add JOSE integration, claim mappings, tests, CI, and docs
- Switch license to EPL-2.0

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Updates submodule to include:
- Unified catalog-based validation with auto-discovery
- New --data-paths, --inference-mode, --artifacts CLI options
- Auto-discovered fixtures from referenced IRIs
- Comprehensive validation suite tests
```
feat: add CI/CD workflows and documentation infrastructure

- Update ci.yml: fix harbour-credentials paths, add PYTHONPATH
- Add cd-docs.yml: MkDocs deployment to GitHub Pages
- Add cd-release.yml: automated releases with changelog
- Add mkdocs.yml: documentation site configuration
- Add docs/: initial documentation structure
  - index.md, getting-started/, credentials/, examples/
- Update pyproject.toml: add [docs] extra dependencies
- Fix test imports: harbour.jose.* → harbour.*
- Add copilot-instructions.md and CLAUDE.md for agent guidance
- Add AGENTS.md with commit/PR guidelines

Refs: repository restructure and CI/CD standardization
```

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Rebuild simpulse-id-credentials on top of the reworked harbour-credentials
submodule. The deleted service-characteristics submodule (core/gaia-x
LinkML imports) is replaced by the harbour import pattern with composition
for Gaia-X data.

LinkML schema:
- All 5 credential types extend HarbourCredential
- Subject types are standalone (no abstract CredentialSubject)
- gxParticipant composition slot for opaque Gaia-X compliance data
- credentialStatus/evidence overridden to required:false (inner VCs pattern)
- importmap.json for cross-repo harbour schema resolution

Artifact generation:
- New FixedShaclGenerator handles gen-shacl bugs (importmap not passed to
  SchemaView, sh:closed default, range:Any → sh:class linkml:Any,
  identifier slot → harbour:id, inherited shape duplication, property
  deduplication from inheritance)
- Replaces generate_from_linkml.py

Examples:
- W3C VCDM2 pattern: string DID issuer, CRSetEntry status, evidence VPs
- Context ordering: W3C v2 → Gaia-X → harbour → simpulseid (domain last)
- Nested gx:LegalPerson composition inside gxParticipant

Build:
- Makefile follows harbour-credentials pattern (python -m pip, bootstrap
  python, parent venv detection, CI support, idempotent setup check via
  importlib.metadata)
- Submodules installed via pip install -e before root package
- Removed service-characteristics submodule

Tests:
- 12 SHACL validation tests (5 valid + 7 invalid examples)
- 10 evidence proof chain tests (signing, verification, full chain)

Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
@jdsika jdsika changed the title Alternative: GaiaX 2411 compliant credentials: Participant, User, Administrator, Base/Envited-Membership feat: rework credentials as domain layer on harbour-credentials Feb 27, 2026
jdsika and others added 5 commits February 27, 2026 21:19
Remove deleted service-characteristics submodule from directory listing,
fix documentation link path, add manifests directory.

Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Establish clear trust chain: Harbour provides Gaia-X compliant
credentials (baseline of trust), SimpulseID references them via IRI
and adds domain-specific data.

Schema:
- Remove gxParticipant slot from simpulseid.yaml
- Add harbourCredential (required URI) to Participant, Administrator, User
- Update importmap.json for renamed harbour-core-credential schema

Examples:
- Remove Gaia-X context and gxParticipant blob from all credentials
- Add harbourCredential IRI to participant/admin/user credentials
- Replace EmailPass/inner-VC evidence VPs with empty VP pattern

Source code:
- sign_examples.py: remove inner VC signing, sign empty VPs directly
- claim_mapping.py: remove Gaia-X mappings, add harbourCredential field

Tests:
- Rewrite test_evidence_proof.py for empty VP pattern (12 tests pass)
- Add participant-missing-harbourCredential.json invalid test
- Update all invalid test data for new schema structure

Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
Replace raw commands in CI workflow with `make` targets, matching
the harbour-credentials CI pattern. Fixes two PR #24 failures:

- Validate job referenced deleted `src/generate_from_linkml.py`
- Test job ran harbour interop tests that need built TypeScript

Also adds `PYTHON_ABS` variable to fix `$(abspath python3)` resolving
to `$CWD/python3` instead of the system binary in CI.

Signed-off-by: jdsika <carlo.van-driesten@vdl.digital>
…modeling

Split credential types into separate imported schema so exclude_imports
filters them from SHACL generation. Harbour SHACL validates the credential
envelope via RDFS inference; simpulseid SHACL validates only subject types
and nested types with sh:closed=true.

Key changes:
- Move credential types to linkml/simpulseid-credentials.yaml
- Add TermsAndConditions class (replaces range: Any)
- Use sdo: (HTTPS) attribute for name to match W3C @Protected context
- Rewrite generate_artifacts.py: 240 to 75 lines, zero post-processing
- Fix revocation registry URIs (fragment to path separator)

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
… ecosystem

- Create ASCS participant DID document (was missing despite being issuer of 4/5 credentials)
- Give Andreas Admin a distinct P-256 key (was identical to Max's key)
- Fix Andreas user DID: tezos-key-1 dangling reference → use wallet-key-1
- Add authentication section to BMW participant DID
- Fix evidence VP holders: Ed25519 did:key (z6Mk) → P-256 did:key (zDn)
  derived from actual JWK keys in DID documents
- Update harbour-credentials submodule with BMW natural person examples

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
jdsika added 3 commits March 9, 2026 10:26
- Add gxParticipant composition slot (range: Any) to Participant/Admin/User
- Add Gaia-X context to all example credentials
- Add signing-key-1 to DID document verificationMethod + assertionMethod
- Add evidence nonce delegation (REPLACED_AT_SIGNING_TIME format)
- Add DomainShaclGenerator with importmap workaround (linkml/linkml#2913)
- Strip sh:class linkml:Any from SHACL output (linkml/linkml#2914)
- Add chain-of-trust integrity tests (40 test cases)
- Add DID method policy documentation
- Bump linkml dependency to >=1.10.0
- Update sign_examples.py with issuer-to-kid mapping

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- Add harbour artifact generation to make generate target
- Add make generate step to CI test-python job
- Both are needed for local JSON-LD context resolution (avoids 404s
  on not-yet-deployed w3id.org context URLs)

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- Migrate all DIDs from did:web to did:ethr (ERC-1056 on Base Sepolia)
- Add did:ethr DID document examples for all ecosystem entities
- Add did:ethr method spec reference documentation
- Complete mkdocs nav: add credential type, integration, and reference pages
- Add Makefile generate dependency to test target
- Fix test fixture nonce placeholder consistency
- Remove deprecated did:web examples and submodules (ontology-management-base, w3id.org)
- Update submodule harbour-credentials to did:ethr migration

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
@jdsika jdsika changed the title feat: rework credentials as domain layer on harbour-credentials feat: SimpulseID credentials — schema-first domain layer on harbour-credentials Mar 9, 2026
jdsika added 10 commits March 10, 2026 15:21
Schema and validation:
- Add DomainContextGenerator to exclude W3C @Protected terms from
  generated JSON-LD contexts
- Fix transitive w3c-vc import in importmap.json
- Override harbour context URL mapping in SHACL test fixture
- Add deprecation/pending notes for schema.org properties
- Add descriptions to SimpulseIdLegalForm enum values
- Document intentional credential type repetition (LinkML limitation)
- Document placeholder URIs in examples/README.md

Markdown lint tooling:
- Add .markdownlint-cli2.yaml config with tuned rules
- Add markdownlint-cli2 pre-commit hook (v0.17.2)
- Add lint-md and format-md Makefile targets
- Add lint-markdown CI job in GitHub Actions workflow
- Fix all existing markdown violations (MD040, MD032)

Update harbour-credentials submodule pointer

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- Add docs/reference/credential-model.md with Mermaid diagrams showing
  how SimpulseID credential types extend HarbourCredential, subject type
  mapping, trust chain, and legal form enum reference
- Expand docs/examples/index.md from stub to full gallery with envelope
  structure, trust chain explanation, and validation instructions
- Fix broken links in docs/did-methods.md (../references/ → references/)
- Add Credential Data Model to mkdocs.yml Reference section
- Add site/ to .gitignore
- Update harbour-credentials submodule pointer

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Replace schema:name with name in gxParticipant nodes of simpulseid
example credentials. The harbour JSON-LD context already maps name
to schema:name, making the prefix redundant.

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- User/Admin: givenName, familyName, email now inside gxParticipant
  as gx:NaturalPerson (harbour-defined extension of gx:Participant)
- Participant: remove redundant name from outer node, keep in
  gxParticipant as gx:LegalPerson
- Update linkml/simpulseid.yaml: remove direct personal attribute
  slots from User/Admin/Participant classes
- Update claim mappings to gxParticipant.* paths
- Add test_natural_person_has_gx_composition integrity test
- Update submodule ref (consolidated examples, minimal skeletons)

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- Replace black, isort, flake8 with ruff for linting and formatting
- Update .pre-commit-config.yaml: 3 hooks → 2 (ruff format + ruff check)
- Update pyproject.toml: remove [tool.black]/[tool.isort], add [tool.ruff]
- Delete .flake8 config (rules moved to pyproject.toml)
- Update Makefile lint/format targets to use ruff
- Auto-fix all ruff formatting and import sorting
- Update harbour-credentials submodule ref

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- Fix test fixture pointing to non-existent harbour.context.jsonld
- Add slot_usage overrides for email/url on SimpulseidParticipant
  (schema:email/schema:url instead of gx:email/gx:url)
- Change gxParticipant type from gx:NaturalPerson to
  harbour_gx:NaturalPerson in User/Admin examples
- Add harbour_gx context URL to all examples
- Remove nonce from evidence VP skeletons (injected at signing time)
- Add stub verifiableCredential to evidence VPs
- Fix T&C url datatype annotation (xsd:anyURI typed literal)
- Update test assertions for harbour VP types and nonce handling
- Update harbour submodule with OWL equivalence patches

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- align did:ethr docs and examples with the Base resolver and IdentityController profile
- keep signer DIDs on local P-256 JsonWebKey controller methods and resource DIDs on external DID Core controllers
- update schema.org usage, signing kids, and bump harbour-credentials to the validated JsonWebKey and OMB fixes

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
- replace legacy make aliases with grouped command centers\n- verify signed SimpulseID storyline outputs with the new Python helper\n- update Harbour and root workflows to the grouped make surface

Signed-off-by: Carlo van Driesten <carlo.van-driesten@bmw.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants