AI Agent Reference — not a marketing page

Gaia-X Participant Credential Wizard — Technical Documentation

Application: gx-signing-tool ("Gaia-X Wizard"), version 2.2.0. This page is the authoritative, machine-readable description of this web application's purpose, features, API surface, and behavior. It is intended to be given to an AI agent as the sole source of context needed to answer questions about the application accurately.

1. What this application does

The Gaia-X Wizard is a browser-based tool that lets an organization (a "Legal Participant") obtain a Gaia-X Compliance Credential — a Verifiable Credential (VC) issued by a Gaia-X Clearing House (also called GXDCH, Gaia-X Digital Clearing House) that attests the organization complies with the Gaia-X Trust Framework.

To do this, the application walks the user through a wizard that:

  • Collects the data needed to describe a Legal Participant (and optionally a Service Offering) as a W3C Verifiable Credential.
  • Collects or generates the identity (DID) and cryptographic key material used to sign that VC.
  • Signs the VC(s), producing signed JWT-VCs.
  • Bundles the signed VC(s) into a Verifiable Presentation (VP) and submits it to a Gaia-X Clearing House compliance endpoint.
  • Receives back a signed Gaia-X Compliance Credential and lets the user download all produced artifacts (VCs, VP, Compliance Credential).

The application can act as its own did:web issuer and VC host (for testing, "non-production mode"), or the user can bring their own DID, verification method, and private key ("production mode") to produce a credential that is valid outside the test/lab environment.

2. Application sections / pages

RoutePurpose
/Home page. Runs the primary onboarding wizard (OnboardingStepperContainer) to create a Legal Participant + Terms & Conditions credential set and obtain a Compliance Credential.
/stepperAlternate, simpler single/multi-shape wizard (StepperContainer) for creating one credential shape (Legal Participant, Service Offering, or Terms & Conditions) end to end.
/legalRegistrationNumberStandalone tool to request a Legal Registration Number (LRN) Verifiable Credential from the Gaia-X notary service, independent of the main wizard.
/playgroundAdvanced Mode only. Sandbox for editing/inspecting VC/VP JSON directly (Monaco editor).
/userGuideHuman-facing, click-through user guide (UI walkthrough, not intended for machine parsing).
/aiDocumentationThis page. Machine-readable technical reference for AI agents. Stable, shareable URL.

A global Sidebar (present on every page) links to all of the above. An Advanced Mode toggle in the sidebar footer reveals additional navigation (Playground, a link to vc-jwt.io) and, in production mode, an "Environment" selector in the top header that lets the user manually pick which Clearing House to submit to.

3. Production mode vs. non-production mode

The single most important behavioral switch in the application is whether the user enables "I'll use my own DID solution" on the first wizard step. This sets isCustomIssuer (wizard state) and isProductionMode (in ClearingHousesContext) together. All downstream steps and API calls branch on this flag.

3.1 Non-production mode (default, isCustomIssuer = false)

  • Purpose: quick testing / demo. Explicitly produces a "fake" credential — not valid for real-world compliance claims.
  • Issuer identity: the application itself acts as the did:web issuer (did:web:vc-jwt.io:api). No user-supplied DID or key is required.
  • Signing: VCs and VPs are signed remotely via the external vc-jwt.io API using a dummy/shared key, not a user-controlled private key.
  • Clearing House: always the default lab Clearing House ("gaia-x", compliance.lab.gaia-x.eu/development). The Environment selector is hidden.
  • Wizard steps skipped: "Identity" (IdentifierStep) and "Private key" (KeyStep) are omitted from the step list entirely.
  • A disclaimer is shown in the UI stating the resulting credential is for testing only.

3.2 Production mode (isCustomIssuer = true)

  • Purpose: obtain a credential that is actually usable outside the test lab.
  • Issuer identity: the user supplies their own did:web:... identifier, a verification method, and a Legal Registration Number (LRN) VC obtained from a notary.
  • Signing key: the user generates or imports an RSA or ECDSA private key in-browser via the Web Crypto API, or uses a hardware-backed key via WebAuthn/FIDO2 (PRF), or signs via a national eID smart card (Web eID, e.g. Estonian eID) — see Section 6.
  • All signing that uses a locally held private key happens client-side; the private key material is never sent to the server.
  • Clearing House: on switching into production mode, the app calls pickRandomClearingHouse() to randomly select a real (non-lab) Clearing House from the meta-registry (see Section 7). Advanced Mode users can override this via the header "Environment" selector.
  • Wizard steps included: "Identity" and "Private key" steps are shown before signing.
  • DID resolution is checked live (see Section 6.4) but an unresolvable DID does not block progress — it only shows a warning.

3.3 Key differences summary

AspectNon-productionProduction
Issuer DIDAuto: did:web:vc-jwt.io:apiUser-supplied did:web:...
Private keyNone (remote dummy key)User-held (browser-generated, imported, WebAuthn, or eID)
Signing locationRemote (vc-jwt.io API)Client-side (or vc-jwt.io API if no local key is present)
Clearing HouseFixed: compliance.lab.gaia-x.eu/developmentRandomly selected real GXDCH, overridable in Advanced Mode
Wizard stepsStart → Legal Person → T&Cs → Sign → Compliance Check → CredentialStart → Legal Person → T&Cs → Identity → Private key → Sign → Compliance Check → Credential
Credential validityTest/demo only ("fake")Intended to be a real, usable Compliance Credential

4. Complete wizard flow (step by step)

Two orchestrators exist and share step components: OnboardingStepperContainer (route /, allRequiredVCs=true, always signs both a Legal Person VC and a Terms & Conditions VC) and StepperContainer (route /stepper, allRequiredVCs=false, signs a single chosen VC shape). Step order below is for the primary / flow.

4.1 Non-production step order

  1. Start
  2. Legal Person
  3. Terms & Conditions
  4. Sign
  5. Compliance Check
  6. Credential (final)

4.2 Production step order

  1. Start
  2. Legal Person
  3. Terms & Conditions
  4. Identity
  5. Private key
  6. Sign
  7. Compliance Check
  8. Credential (final)

4.3 Step-by-step behavior

  • Start: Landing/intro step. Toggling "own DID solution" flips isCustomIssuer/isProductionMode, resets the DID and private-key fields, and re-randomizes the Clearing House selection.
  • Legal Person: user picks a VC "shape" (participant, service, or termsAndConditions) and fills a Formik-driven form to build the credentialSubject values for that shape.
  • Terms & Conditions: the user signs the Gaia-X Terms & Conditions VC (required in the multi-VC "/" flow).
  • Identity (production only): collects the issuer did:web, verification method (auto-resolved live against the DID, see 6.4), a unique VC id, a T&C VC id, and a Compliance VC id. "New" buttons generate UUID-based self-hosted resolvable URLs of the form {origin}/api/credentials/{uuid}. All fields are required (Formik validation blocks Next until valid).
  • Private key (production only): generate or import an RSA/ECDSA key pair, or configure WebAuthn/FIDO2 or eID-based signing. Next is disabled until a usable key/signing method is present.
  • Sign: signs the created VC(s) — locally via Web Crypto if a private key is present, otherwise via the external vc-jwt.io API. Resulting signed JWTs are uploaded to the self-hosted /api/credentials/{id} endpoint when the VC id is self-hosted. Shows a success toast "Signature done with success!" on completion.
  • Compliance Check: user selects which signed credentials to include, builds an "enveloped VC" reference array, signs a VP (locally or via vc-jwt.io), POSTs it to the selected Clearing House's compliance endpoint, and on success stores/uploads the returned Compliance Credential. A minimum 1200ms loading screen is shown; a confetti animation fires on success.
  • Credential (final): displays all signed VCs, the VP, and the resulting Compliance Credential. "Download all credentials" zips every artifact (as JWT or JSON) via JSZip/file-saver. "Restart" resets the wizard to step 0 after a confirmation modal.

4.4 Transition / gating rules

  • Navigation uses goToNext()/goToPrevious(), bounded to [0, steps.length - 1], plus setActiveStep() for direct jumps.
  • On a successful compliance check, activeStep is explicitly set past the last enumerated step to display the final Credential step.
  • Each step's "Next" button is disabled until that step's completion condition is met, e.g.: Private key step requires privateKeyUse.privateKey to be set; Identity step requires Formik isValid; Compliance Check requires at least one selected document and !isComplianceLoading.

5. Processing steps, filters, and compatibility checks

5.1 VC/VP validation before signing/submission (useVPValidation)

Selected wallet documents are grouped by credentialSubject.type and checked against these rules:

  • At least one credential of type gx:LegalParticipant must be present.
  • A gx:GaiaXTermsAndConditions VC signed by every distinct issuer present in the selection must exist (Legal Registration Number VCs are excluded from this check since they are already Gaia-X-signed).
  • Exactly one gx:legalRegistrationNumber VC must be present per participant.

Each rule produces a result object with isValid, count, min, and human-readable messages (e.g. "You must sign terms and conditions for issuer <truncated DID>"). Validation failures are surfaced inline in the UI, not thrown as exceptions.

5.2 Credential format negotiation

Compliance submission and credential-offer retrieval support three formats via an Accept header: application/json, application/vc+jwt, and application/vp+ld+jwt. Responses are parsed based on their returned content-type: application/vc+jwt decodes a single VC from a JWT; application/vp+ld+jwt decodes a VP and every VC embedded within it. Parsed results are normalized into a common displayable document shape used throughout the UI.

5.3 Identity / DID compatibility check (Section 6.4 has full detail)

On blur of the issuer DID field (production mode), the app resolves the DID against a DID verification service. An unresolvable DID surfaces a non-blocking warning; it does not stop the user from proceeding, but flags that the resulting VCs "may not be compliant."

5.4 Meta-registry / trusted issuer / Clearing House filtering (Section 7 has full detail)

The list of candidate Clearing Houses is pulled from a Gaia-X meta-registry of trusted issuers and filtered to only v2 endpoints; random selection additionally filters out lab/test endpoints and requires both a registry and a notary endpoint to be present.

5.5 Extension / hardware compatibility

  • WebAuthn/FIDO2: requires a browser and authenticator that support the PRF extension for key derivation; a random challenge is fetched from /api/webauthn/challenge for each signing operation.
  • Web eID (national eID smart cards, e.g. Estonian eID): requires the Web eID browser extension and companion native application to be installed; the app hashes the payload with the algorithm the card reports supporting (SHA-224/256/384/512) via /api/webeid/prepareSignature, then verifies the resulting signature's certificate is not revoked via OCSP before building a JWS in /api/webeid/getEidJws.
  • Certificate chains used for eID/PKI signing must include an Authority Information Access (AIA) extension; its absence is treated as an error ("Certificate does not include AIA extension") in both the cert-chain-building and eID JWS endpoints.

6. Identity, keys, and signing in depth

6.1 DID types used

  • did:web — the only DID method used by this application, both for the app's own auto-issued identity (non-production) and for user-supplied issuer identities (production).
  • The app can itself host a did:web document: GET /api/did.json serves the app's own DID document, and /.well-known/x509CertificateChain.pem serves its own hosted certificate chain.

6.2 Private key options (production mode)

  • Generate or import an RSA or ECDSA key pair directly in the browser via the Web Crypto API. The private key never leaves the browser.
  • WebAuthn/FIDO2 hardware token, using the PRF extension to derive/unlock key material; requires a fresh random challenge per operation (/api/webauthn/challenge).
  • Web eID national ID card signing (e.g. Estonian eID) using the installed Web eID browser extension; signing happens on the card itself, the server only pre-hashes the payload and OCSP-checks the certificate.

6.3 Signing paths

  • Local signing: used whenever a usable private key/signing method is present in the browser (Web Crypto key, WebAuthn, or eID). VCs and VPs are signed entirely client-side.
  • Remote signing via vc-jwt.io: used in non-production mode (no local key exists) and as a fallback whenever no local key is present. The unsigned "enveloped VC" payload is sent to the external vc-jwt.io API for signing.

6.4 DID resolution / trust check

On blur of the issuer DID field, the app calls GET /api/did-verification?did=...&isTrusted=..., which proxies to an external DID verification service. If verification methods are returned, they populate a dropdown and the first one is auto-selected. If the DID cannot be resolved or the call errors, an amber warning is shown: "This DID:web identifier could not be resolved. The generated VCs may not be compliant." This is advisory only and does not block progression.

7. Meta-registry, Trusted Scope, and Clearing House handling

  • The list of known Clearing Houses is fetched via GET /api/clearing-houses, which itself calls a Gaia-X meta-registry of trusted issuers (REGISTRY_TRUSTED_ISSUERS_URL, default https://registry.lab.gaia-x.eu/v2/api/trusted-issuers) and keeps only entries whose endpoint URL contains "/v2".
  • Random Clearing House selection (pickRandomClearingHouse, run on mount and whenever the user switches into production mode) excludes any candidate whose endpoint contains "lab.gaia-x" (i.e. lab/test endpoints) and requires the candidate to have both a non-empty registry endpoint and a non-empty notary endpoint.
  • The default fallback Clearing House ("gaia-x", compliance.lab.gaia-x.eu/development) is forced whenever the user switches back to non-production mode.
  • In Advanced Mode + production mode, the header "Environment" selector lists all providers except the literal value "any" and any provider whose name contains "gaia" (to avoid re-listing lab environments), letting the user manually override the Clearing House.
  • The selected Clearing House name and the selected Gaia-X deployment path (v2 vs. development, corresponding to Gaia-X release names "Tagus"/"Loire") are persisted to localStorage under the keys clearingHouse and selectedGxDeploymentPath.
  • The compliance submission URL is built as https://{selectedClearingHouse.complianceEndpoint}/api/credential-offers/standard-compliance when a custom issuer is used, or the default NEXT_PUBLIC_COMPLIANCE_URL otherwise.

8. API endpoints (pages/api)

All endpoints are Next.js Pages Router API routes under /api/. Unsupported HTTP methods return 405 with body "<METHOD> not allowed".

EndpointMethodPurposeInputOutput / notable errors
/api/clearing-housesGETList available Gaia-X Clearing Houses from the trusted-issuers meta-registry, filtered to v2 endpoints.none{ [category]: string[] } of endpoint URLs
/api/credential-offersPOSTSubmit a signed Verifiable Presentation to a Clearing House compliance endpoint and receive a Compliance Credential.body: { clearingHouse?, verifiablePresentation }; Accept header selects response formatCredentialOffersApiResponseData { data, clearingHouse, jwt?, format }; JWT responses are decoded into a displayable document
/api/did-verificationGETCheck whether a DID resolves and list its verification methods.query: did, isTrustedproxied verification-method list from the external DID verification service
/api/legalRegistrationNumberGETRequest a Legal Registration Number (LRN) VC from the Gaia-X notary.query: vcid, type (EORI | vatID | leiCode), value, subjectId, clearingHouseJSON-LD VC document; 400 "Invalid registration number" on invalid input; 502 "Rate limit exceeded" passthrough
/api/credentials/[...id]GET, POST/PUT/PATCHSelf-hosted storage/retrieval of a VC by id — this is the resolvable hosting endpoint referenced by self-hosted VC ids created in the Identity step.GET: id path param. POST/PUT/PATCH: id + raw VC bodystored/retrieved VC text, persisted via a pluggable storage service (disk / S3 / in-memory, selected by STORAGE_PROVIDER)
/api/registry/[vcid]GETRetrieve a VC in a registry/did.json-compatible shape.URL path (did + vcid)[VC] as a JSON array
/api/did.jsonGETServe the application's own did:web DID document.noneJSON DID document
/.well-known/x509CertificateChain.pemGETServe the application's own hosted x509 certificate chain.nonePEM text (download headers if Accept: application/x-pem-file)
/api/certchain/[id]GET, POSTStore/retrieve a user-uploaded x509 certificate chain (used for eID/PKI signing). POST walks the AIA caIssuer chain leaf → intermediate → root.POST body: leaf certificate. GET: id{ certChain } on POST; PEM text on GET; 404 { message: "Certificate chain not found" }; error "Certificate does not include AIA extension" if AIA is missing
/api/x509/[...id]GETRetrieve a named X.509 certificate from the keychain service.path id (".crt"/".pem" suffix stripped)certificate content
/api/webauthn/challengeGETGenerate a random 32-byte challenge for WebAuthn/FIDO2 PRF-based key unlock.nonenumber[] of raw bytes
/api/webeid/getEidJwsPOSTBuild a JWS from a Web eID card signature after OCSP-checking the signing certificate.body: { payload, header, signature, certificate }{ jws, valid, status }; 400 if certificate lacks AIA extension; { jws: "", valid: false, status } (200) if OCSP status is not "good"
/api/webeid/prepareSignaturePOSTHash the JWT header+payload with the algorithm requested by the eID card before signing.body: { payload, header, supportedSignatureAlgorithms: { hashFunction } } — SHA-224/256/384/512{ hash, hashFunction }; 400 on unsupported hash function
/api/cesPOSTForward a credential event to the Gaia-X Credentials Event Service (CES).body: { event, deploymentPath } — "v1" routes to ces-v1.lab.gaia-x.eu, else ces-development.lab.gaia-x.eu201 empty on success; 400/502 with message on failure

9. Success and error cases

  • Global toast error handler: shows the error message plus any error.response.data.errors[] joined by newline, for 5 seconds.
  • Compliance call failure: toast "Compliance call failed: <detail>", where <detail> is a joined results array from a structured backend message, or the raw error message/text.
  • LRN request failure: HTTP 502 from the notary is surfaced as "Rate limit exceeded"; other failures as HTTP 400 "Invalid registration number".
  • Unresolvable issuer DID: non-blocking amber warning banner on the Identity step — does not prevent progression.
  • x509 certificate chain not found: 404 { message: "Certificate chain not found" }.
  • Missing AIA extension on a certificate: thrown/returned as "Certificate does not include AIA extension" (certchain and eID endpoints).
  • eID OCSP check: if the certificate status is not "good", the endpoint returns 200 with { jws: "", valid: false, status } — the client must treat this as a signing failure despite the 200 status.
  • Unsupported HTTP method on any API route: 405 with body "<METHOD> not allowed".
  • Other API failures: generic 400/500 with error.message.
  • VP/VC validation failures (useVPValidation): surfaced inline per rule in the UI (not thrown), with counts and human-readable messages.
  • Signing success: green toast "Signature done with success!" after the Sign step completes.
  • Compliance success: confetti animation fires and the wizard auto-advances to the final Credential step.