Skip to main content

Domains and Exposure

Wallets, verifiers, and relying parties reach Procivis One from outside your network. Core publishes URLs for them to call: credential offers, proof requests, DIDs, schemas, revocation lists, and published trust lists all point back to Core's base URL. If those URLs are not reachable from a phone or a remote service, issuance and verification fail.

For testing and development, any reachable URL works. For production, set your domain before you issue or publish anything you intend to keep. Changing Core's base URL later breaks the URLs embedded in what you have already issued or published.

Where to start​

Public and internal services​

ServiceHostnameReachable fromCalled by
Frontend and BFF, via oauth2_proxy<domain>InternetOperators' browsers
Keycloakkeycloak.<domain>InternetOperators' browsers, during sign-in
Corecore.<domain>InternetWallets and verifiers
Bridgebridge.<domain>InternetOIDC relying parties
WRPRwrpr.<domain>InternetWallets, certificate authorities
Databases, Redis—Internal onlyProcivis One services

Core serves both public protocol endpoints (/ssi, /.well-known) and management endpoints (/api) on the same hostname. To keep management endpoints off the public internet, see API Endpoint Zones. Core's /health and /metrics endpoints are for internal use and should not be routed publicly.

To serve different domains, for example one per ecosystem or customer, run separate Core instances, each with its own base URL.

URL settings​

Each section below covers one URL and lists every setting that must match it. The Quick start location column shows where each setting lives in the Full Stack Quick Start bundle. If you have reorganized your configuration, the setting names stay the same.

Core settings are shown as YAML paths, followed by the environment variable that overrides them. See Core configuration layers for details of configuration merging.

Core public URL​

The URL wallets and verifiers use to reach Core. On a domain: https://core.<domain>.

ServiceSettingQuick start location
Coreapp.coreBaseUrl (ONE_app__coreBaseUrl)env/.core.env

Desk URL​

The URL operators use to reach the Desk. On a domain: https://<domain>.

ServiceSettingQuick start location
BFFfrontend.urlenv/.bff.env
BFFsts.token.issenv/.bff.env
oauth2_proxyredirect_url (<Desk URL>/oauth2/callback)conf/oauth2_proxy/oauth2-proxy.cfg
Keycloaklogin-client redirect URIs, web origins, post-logout redirect URIsmaster-realm.json

Identity provider URLs​

The URLs services use to sign users in and obtain or validate tokens. For the starter Keycloak on a domain, these start with https://keycloak.<domain>/realms/master. When you connect your own identity provider, use its URLs instead.

ServiceSettingQuick start location
BFFsts.iam.tokenValidation.issenv/.bff.env
BFFsts.iam.tokenValidation.jwksUrienv/.bff.env
BFFauth.technicalUserCredentials.iamTokenEndpointUrlenv/.bff.env
BFFfrontend.iamLinkenv/.bff.env
Bridgespring.security.oauth2.client.provider.keycloak.token-urienv/.bridge.env
WRPRspring.security.oauth2.client.provider.keycloak.token-urienv/.wrpr.env
oauth2_proxyissuerURLconf/oauth2_proxy/alpha-config.yml
oauth2_proxybackendLogoutURLconf/oauth2_proxy/alpha-config.yml
Keycloak (starter only)KEYCLOAK_HOSTNAMEenv/.keycloak.env

Service-to-service URLs​

The URLs the BFF, Bridge, and WRPR use to reach other Procivis One services.

ServiceSettingQuick start location
BFFcore.api.url, bridge.api.url, wrpr.api.urlenv/.bff.env
Bridgecore.api.urlenv/.bridge.env
WRPRcore.api.urlenv/.wrpr.env

These can point to either the public hostname, such as https://core.<domain>, or the internal service name, such as http://core:3000. The localhost bundle uses internal names; the domain bundle uses public hostnames.

Routing and certificates​

The hostnames your reverse proxy routes and the domains oauth2_proxy accepts.

ServiceSettingQuick start location
TraefikHost() rules for each public servicedocker-compose.yml
Traefikacme.email (Let's Encrypt account)docker-compose.yml
oauth2_proxywhitelist_domainsconf/oauth2_proxy/oauth2-proxy.cfg

Local testing with a tunnel​

On localhost, Core's base URL is http://localhost:3000, which a mobile wallet cannot reach. To test wallet flows without a domain, expose Core through a tunnel such as ngrok or Cloudflare Tunnel.

warning

A tunnel makes all of Core reachable from the internet, including the /api management endpoints. These are protected only by the starter static token, which every installation shares. Replace the starter tokens before you start a tunnel.

  1. Start a tunnel to port 3000. Use a stable hostname: if the tunnel URL changes on restart, anything issued under the previous URL stops working. For example, with ngrok and a static domain (one included in ngrok free accounts, shown in the ngrok dashboard):

    ngrok http 3000 _-url https://<your-static-domain>
  2. Set the tunnel URL as Core's base URL in env/.core.env:

    ONE_app__coreBaseUrl="https://<your-static-domain>"
  3. Apply the change:

    docker compose up -d

    Compose recreates the services whose configuration changed.

Once the tunnel is set up, wallets can receive issuance and read your verification requests.

Only Core needs a tunnel for issuance and verification. Operator sign-in and the Desk continue to work on http://localhost.

Moving from localhost to a domain​

The simplest path is a fresh domain deployment, following Option B in the Full Stack Quick Start. Anything issued or published under localhost URLs is not valid on the new domain, so there is little to carry over.

If you changed any starter secrets or keys in your localhost deployment, copy those changes into the domain bundle before starting.

Keeping existing Keycloak data​

The starter realm is imported only on first start. If you reuse an existing Keycloak database instead of starting fresh, the realm keeps its localhost URLs. Update them in the Keycloak admin console:

  1. Sign in at https://keycloak.<domain>/admin with the bootstrap admin credentials (default: admin / admin).

  2. Open the login-client client and set:

    SettingValue
    Valid redirect URIshttps://<domain>/oauth2/callback
    Valid post logout redirect URIshttps://<domain>
    Web originshttps://<domain>
  3. Change the admin password. The default is shared by every installation.

Existing reverse proxy or load balancer​

The domain bundle includes Traefik, which terminates TLS and requests certificates from Let's Encrypt. If your server already runs a reverse proxy, or sits behind a load balancer that terminates TLS, use that instead:

  1. Remove the traefik service and the traefik.* labels from docker-compose.yml.

  2. Publish the public services' ports to the host. Bind them to 127.0.0.1 if your proxy runs on the same server:

    oauth2_proxy:
    ports:
    - "127.0.0.1:4180:4180"
    core:
    ports:
    - "127.0.0.1:3000:3000"
    keycloak:
    ports:
    - "127.0.0.1:8080:8080"
    bridge:
    ports:
    - "127.0.0.1:9000:9000"
    wrpr:
    ports:
    - "127.0.0.1:9001:9001"
  3. Route each hostname to its port:

    HostnameUpstream
    <domain>oauth2_proxy, port 4180
    core.<domain>core, port 3000
    keycloak.<domain>keycloak, port 8080
    bridge.<domain>bridge, port 9000
    wrpr.<domain>wrpr, port 9001

    If you change a service's listening port, such as Core's app.serverPort, update its upstream to match.

  4. Forward the X-Forwarded-Proto, X-Forwarded-Host, and X-Forwarded-For headers. Services use them to generate correct https URLs behind the proxy.

Remove the Traefik settings from Routing and certificates; all other URL settings stay the same.