ExOpenid4vc

ExOpenid4vc provides an Elixir-native boundary for the OpenID4VCI metadata and offer objects Delegate will need as the issuance surface becomes more standards-complete.

Current scope:

This package does not yet implement full issuance or presentation protocol handlers.

Status

Current support:

Current proof verification boundary:

Supported holder-binding methods:

Intentionally deferred:

Installation

def deps do
  [
    {:ex_openid4vc, "~> 0.1.0"}
  ]
end

Example

configuration =
  ExOpenid4vc.credential_configuration("jwt_vc_json",
    scope: "agent_delegation",
    cryptographic_binding_methods_supported: ["did:web"],
    credential_signing_alg_values_supported: ["ES256"],
    proof_types_supported: %{
      "jwt" => %{
        "proof_signing_alg_values_supported" => ["ES256"]
      }
    },
    credential_definition: %{
      "type" => ["VerifiableCredential", "AgentDelegationCredential"]
    }
  )

metadata =
  ExOpenid4vc.issuer_metadata("https://issuer.delegate.local",
    credential_configurations_supported: %{
      "agent_delegation_jwt" => configuration
    }
  )

Testing And Parity

The library is tested with:

Refresh upstream parity fixtures with the maintainer-only recorder:

cd libs/ex_openid4vc/scripts/upstream_parity
pnpm install
pnpm run record:released

When developing in this workspace before ex_did is published on Hex, use the local sibling dependency override:

cd libs/ex_openid4vc
EX_OPENID4VC_USE_LOCAL_DEPS=1 mix deps.get
EX_OPENID4VC_USE_LOCAL_DEPS=1 mix test

Run live cross-implementation property checks after installing the maintainer dependencies:

cd libs/ex_openid4vc
EX_OPENID4VC_LIVE_ORACLE=1 mix test test/upstream_live_property_test.exs

The parity model is intentionally split:

The current intentionally manual parity surfaces are:

Those remain manual because oid4vc-ts currently does not expose stable public builder APIs for them. They are still documented and covered by direct Elixir tests, but they are not claimed as cross-implementation contractual parity.

Normal mix test and normal ex_openid4vc usage do not require Node, pnpm, or network access. The committed fixtures are the contract.

Run the package release gate locally with:

mix release.gate

Maintainers should include the live oracle checks before cutting a release:

EX_OPENID4VC_LIVE_ORACLE=1 mix release.gate --include-live-oracle

Open Source Notes

Maintainer Workflow

ex_openid4vc currently lives in the delegate monorepo and is mirrored into the standalone ex_openid4vc repository for publishing and external consumption.

The intended workflow is:

  1. make library changes in libs/ex_openid4vc
  2. run mix release.gate
  3. run EX_OPENID4VC_LIVE_ORACLE=1 mix release.gate --include-live-oracle
  4. sync the package into a clean checkout of github.com/bawolf/ex_openid4vc
  5. review and push from the standalone repo

A helper script for the sync step lives at scripts/sync_standalone_repo.sh.

The standalone repository also carries GitHub Actions workflows for:

The publish workflow expects a HEX_API_KEY repository secret in the standalone ex_openid4vc repository. Once triggered, it publishes to Hex and then creates the matching Git tag and GitHub release automatically.