Unirail

Connect Infisical with OIDC

Give Unirail read-only access to one folder of your Infisical through OIDC federation, so provider credentials never leave your vault.

Unirail never stores your provider credentials. Instead, a machine identity in your Infisical trusts Unirail's OIDC issuer, and Unirail logs in as that identity whenever it needs to call a provider. You grant it read access to one folder, and you can revoke it by deleting the identity.

You'll do this once per Unirail environment: sandbox reads your test credentials, production reads your live ones.

How it works

  1. Unirail signs a JWT for your organisation and environment with its own key, published at its JWKS URI. The token lives for five minutes.
  2. Infisical checks the token against the issuer, subject and audience you configure on the identity, then returns a short-lived access token for that identity.
  3. Unirail reads the folder with that token and keeps the values in memory only, for at most five minutes. They are never written to Unirail's database, KV, logs or traces, and there is no client secret or vault token in Unirail to leak.

Before you start

  • An Infisical project (Infisical Cloud in the US or EU, or self-hosted) and permission to create machine identities and project roles in it.
  • A Unirail organisation, and the environment you're connecting open in the dashboard.

Lay out the folder

In the Infisical environment this Unirail environment should read (for example dev for sandbox, prod for production), create a /unirail folder with one sub-folder per provider. Each provider's keys go in its folder, named exactly as below:

ProviderPathHolds
Enable Banking/unirail/enablebanking/APPLICATION_IDEnable Banking application id (the JWT kid)
/unirail/enablebanking/PRIVATE_KEY_PEMThe application's RSA private key, PKCS#8 PEMsecret
Plaid/unirail/plaid/CLIENT_IDPlaid client id for this environment
/unirail/plaid/SECRETPlaid secret for the matching Plaid environment (sandbox or production)secret
Yapily/unirail/yapily/APPLICATION_IDYapily application id
/unirail/yapily/APPLICATION_SECRETYapily application secretsecret

The general shape is <basePath>/<railId>/<KEY>. /unirail is the default base path; you can choose another when you bind the environment.

Add Infisical as a secret source

In the dashboard, open Secrets and add an Infisical source with:

  • Name: anything that tells you which project it is.
  • Site URL: https://app.infisical.com, https://eu.infisical.com, or your self-hosted URL.
  • Project ID: from the project's settings in Infisical.

A source belongs to the organisation, so every environment can use it.

Copy the federation values

Still on Secrets, the environment shows the values Infisical needs to trust Unirail:

ValueLooks like
Issuerhttps://api.unirail.dev/oidc
Discovery URLhttps://api.unirail.dev/oidc (Infisical appends /.well-known/openid-configuration itself)
JWKS URIhttps://api.unirail.dev/oidc/jwks.json
Subjectorg:<orgId>:env:<envId>, unique to this environment
Audiencehttps://api.unirail.dev/oidc

Copy them from the dashboard rather than typing them: the subject is what stops one environment's token from reading another environment's folder.

Create a machine identity

In Infisical, open Organization → Access Control → Identities and create an identity named after the environment, for example unirail-sandbox, with no organisation role. It only needs access to one project.

Add OIDC auth to the identity

On the identity, add the OIDC Auth method and fill in:

  • OIDC Discovery URL: the discovery URL.
  • Issuer: the issuer.
  • Subject: the subject, exactly.
  • Audiences: the audience.
  • Leave Claims empty, and keep the access token TTL short. Unirail logs in again whenever it needs to.

If Infisical added another auth method to the identity by default, such as Universal Auth, remove it so the identity has no client secret.

Give it read access to /unirail

In the project, create a custom role, for example unirail-read, that can only read secrets, with two conditions:

  • Environment is the one you laid out in the first step (for example dev).
  • Secret path matches /unirail/**.

Then add the identity to the project under Access Control → Machine Identities with that role. Nothing else: no write, no other environments, no other paths.

Bind and verify in Unirail

Back on the environment's Secrets page, bind it with:

  • Machine identity ID: the identity's id from Infisical.
  • Infisical environment: the environment slug, such as dev.
  • Base path: /unirail, unless you chose another.

Press Bind environment, then Verify access. Unirail logs in with its OIDC token, lists the base path and reports the key names it found. It never shows or stores the values.

Add connections

Open Connections and add each provider with the matching provider environment: sandbox in a test environment, production in a live one. Unirail looks under <basePath>/<railId>/ and its check reports how many of the required keys it found.

Revoking access

Delete the identity in Infisical, or remove its OIDC auth method. Unirail's next login fails, cached values expire within five minutes, and new provider calls stop until you bind a new identity.

Things to know

  • Cold starts. The first provider call on a fresh Unirail worker adds one round trip to Infisical before it can call the provider.
  • Availability. If Infisical is unreachable, workers that already hold credentials keep working until they expire, and new operations on fresh workers fail closed rather than falling back to anything stored.
  • In memory is still in use. Unirail holds credential values in memory while it calls a provider. "Never stored" means never persisted, never logged, and only ever read through a grant you can revoke.

Troubleshooting

SymptomLikely cause
Verify access says login failedThe issuer, subject or audience on the identity doesn't match the dashboard exactly, or the identity has no OIDC auth.
Verify access says forbiddenThe identity isn't in the project, or its role lacks read on that environment or path.
Verify access finds no keysThe source environment or base path is wrong, or the folder is empty.
A connection finds some keys but not allA key name differs from the table above. Names are case-sensitive.
Verify access can't reach InfisicalThe site URL is wrong, or your self-hosted Infisical isn't reachable from the internet.

On this page