Architecture
How OpenEPCIS handles identity, isolation, events, and GS1 conformance — the four things that distinguish the platform.
Four cross-cutting concerns shape every OpenEPCIS module.
- Authentication: one identity, three ways in
- Multi-tenant isolation at the data layer
- Live events without polling
- GS1 conformance contract
Authentication: one identity, three ways in
A customer's users can sign in with whichever credential their organisation already uses:
- OIDC bearer token — for systems integrated with the customer's identity provider.
- Session cookie — for browser-based access to admin or operator UIs.
- API key + secret — for service-to-service traffic and SDK calls.
All three flows converge on a single authenticated identity. Each customer (tenant) lives in its own Keycloak realm, resolved automatically from the request's hostname. Roles travel on the identity and gate the REST endpoints.
For one-off sharing — for example sending a regulator a direct link to a specific batch — the platform mints short-lived capability tokens scoped to one URL and one HTTP method. No broader account access is granted.
Wallet-agnostic Verifiable Credentials (OID4VC)
The same Keycloak realm that handles sign-in is also a Verifiable Credential Issuer. Keycloak's native implementation of the OpenID Foundation's verifiable-credentials stack — OID4VCI for issuance, OID4VP for verifiable-presentation flows, SIOPv2 for self-issued OpenID identities — turns each tenant's realm into a standards-conformant VC issuer without bolting on a separate identity stack.
Credentials are issued in whichever format the holder's wallet expects. The platform's lead is sd-jwt-vc because selective disclosure is part of the format itself — a holder can prove "recycled-cobalt share is above the regulated threshold" without revealing the exact percentage — and the other accepted formats are jwt_vc_json, ldp_vc and ISO mDoc.
Because the issuance surface is open OpenID-Foundation protocol rather than a proprietary wallet integration, the platform interoperates with every OID4VC-compliant wallet already in production or in pilot — the EU Digital Identity Wallet under eIDAS 2.0, the Catena-X Managed Identity Wallet inside its dataspace, enterprise business wallets, sector-specific wallets, holder apps on mobile. OpenEPCIS doesn't ship a wallet and doesn't pick a winner; it speaks the protocol every wallet camp is converging on.
Trusted subjects
The verifier side is where the real interoperability work lives. A credential is only as useful as the verifier's certainty that the issuer is who they claim to be. OpenEPCIS expects to maintain a globally-scoped trust list of accepted issuers — not EU-only and not product-category-only — so a verifier looking at a presented credential can confirm the issuer's identity, the credential's binding, and the revocation status against a single, openly-maintained list rather than chasing per-region or per-sector registries.
What ships today is the protocol layer — OID4VCI / OID4VP / SIOPv2 issuance and verification surfaces on every Keycloak realm. The named credential schemas (EPCISCommissioningCredential, DPPBatteryPassportCredential, EUDRDueDiligenceCredential, UNTPDigitalConformityCredential and the rest) and the capture-to-issuance pipeline that fires a VC the moment the underlying event or attestation is recorded are the next strategic roadmap item.
Multi-tenant isolation at the data layer
This is the architecture's headline.
The application does not rewrite queries to inject a tenant filter. It forwards the authenticated identity to OpenSearch and lets OpenSearch's Security plugin enforce Document-Level Security server-side. If the application's authorisation code is wrong, the data layer is still right.
flowchart TD
ar(["Authenticated<br/>request"]) --> client["<b>OpenSearch client</b><br/>request-scoped"]
client --> spi["<b>Identity forwarded</b><br/>to the data layer"]
spi --> os["<b>OpenSearch Security</b><br/>validates identity<br/>applies tenant DLS<br/>returns matching docs only"]
classDef accent fill:#fef3f2,stroke:#d92d20
class spi accent
Background workloads (capture pipelines, scheduled subscriptions) use an explicit admin path — no silent privilege change at runtime.
Where it's still binary
Access today is binary per tenant: a user sees everything in their organisation or nothing. Row-level scoping (GLN-, EPC-range-, or biz-location-bound visibility) is a roadmap item.
Live events without polling
EPCIS subscriptions in OpenEPCIS are live — matches fire at the moment an event is indexed, not on a poll interval. Same model serves WebSocket clients and HTTP webhooks:
flowchart TD
cap(["/capture"]) --> store["<b>Event store</b><br/>hash-deduplicated<br/>tenant-isolated"]
store --> match["<b>Subscriptions matched live</b><br/>against new event"]
match --> ws["WebSocket"]
match --> wh["Webhook"]
Scheduled (cron-style) subscriptions sit alongside streaming for clients that want batch-style delivery — nightly digests, periodic compliance pulls — and clients opt into them explicitly.
Pagination on long-running queries survives client reconnects, so a regulator pulling six months of events can drop and resume without restarting the scan.
GS1 conformance contract
Three discipline rules apply platform-wide. Together they make every OpenEPCIS deployment conformant with GS1 EPCIS 2.0 and the GS1 Conformant Resolver standard.
1. Identifiers are GS1 Digital Link at rest
Every EPC, business location, and read point is stored as a Digital Link URI (e.g. https://id.example.com/01/04012345999990/21/123456). Clients that still expect EPC URN form get it on demand at query time — but the canonical form, the form everything compares against, is Digital Link.
2. Masterdata lives on the resolver, not inside events
EPCIS documents are lean. They carry identifiers; the descriptive payload (product name, organisation details, place data, certifications) sits on the resolver and is fetched by the consumer that needs it. Masterdata is registered once via POST /products/{gtin}, POST /organizations/{gln}, POST /places/{loc} — and from that single record, the resolver auto-derives a dozen standard GS1 link types (gs1:pip, gs1:productImage, gs1:audioFile, gs1:relatedVideo, gs1:safetyInfo, gs1:certificationInfo, gs1:nutritionalInfo, gs1:instructions, gs1:recallStatus, gs1:serviceInfo, gs1:productSustainabilityInfo).
3. The deployment is self-describing
A working OpenEPCIS instance publishes the discovery document the GS1 Conformant Resolver standard expects — at the spec-mandated path /.well-known/gs1resolver. The point is that any downstream system (GS1's own Global Office resolver, a partner registry, a market-surveillance tool) can find the deployment automatically and read what it offers, instead of being hand-configured against it. That's what "GS1 Conformant" means in the standard's sense.
See also
- Feature matrix — capabilities by edition.
- Modules → Resolver — the GS1 conformance surface.
- Modules → EPCIS Events — capture, query, and streaming subscriptions in context.
- Roadmap — Verifiable Credentials, sub-tenant scoping, event-to-resolver promotion.