Open source OAuth 2.0 token relay

Secure OAuth2 tokens,
never on disk.

OAUTH2Relay gets the access token, keeps it in memory, renews it before it expires and adds it to every request your services make. Credentials come from your environment or your secrets manager, never from code.

Apache-2.0 Linux, macOS, Windows Single static binary

What is OAUTH2Relay?

A small relay.
Zero token storage.

OAUTH2Relay sits between your services and an API that needs OAuth 2.0. It logs in to the identity provider, holds the access token in memory, and adds it to each request it relays. Your services call the relay with no token logic of their own. Tokens are never written to disk or a database, and the client secret or signing key comes from an environment variable or a secrets manager, so the configuration file holds no secrets.

Tokens in memory only

Access and refresh tokens live in process memory and disappear when the relay stops.

Credentials from your environment

${env:NAME} placeholders, or AWS Secrets Manager, HashiCorp Vault and Azure Key Vault.

Renewed in the background

The token is renewed at 80% of its lifetime, by refresh token or a new login, so requests never wait for it.

Ready to operate

Health checks, Prometheus metrics, structured JSON logs, TLS and graceful shutdown built in.

Built for server-to-server integrations: backend services, batch jobs and platforms that call third-party or internal APIs protected by OAuth 2.0.

Advantages

Built for security.
Simple to run.

Secure by default

  • No secrets in config: credentials come from ${env:NAME} or a secrets manager.
  • Masked logs: secrets and tokens are redacted from every log line, even in debug mode.
  • Locked-down relaying: API key for callers, allow-listed hosts and blocked internal addresses (SSRF protection).

Cloud-native ready

  • One static binary for Linux, macOS and Windows; runs in any container or under systemd.
  • Liveness and readiness endpoints for Kubernetes, and graceful draining on shutdown.
  • HTTPS with automatic certificate reload, e.g. from cert-manager.

Helps with compliance

  • No credentials in code or config files, and no tokens on disk to protect or audit.
  • Every request logged once with a request ID that is passed to the API, for traceability.

Simple operations

  • No database, no cache, no state to back up: just a configuration file.
  • Prometheus metrics for requests, token renewals and expiry, with suggested alerts.
  • --check-config validates a configuration in CI before it is deployed.

Resilient by design

  • Keeps using the current token while the identity provider is down, and retries with backoff.
  • Callers get 503 during an outage so they can retry, and recover without a restart.
  • Rotated secrets are picked up on a schedule, without restarting.

How does it work?

Four steps.
No secrets left behind.

Your service OAUTH2Relay (token in memory) Third-party API

Step 1 of 4

Credentials injected at startup

The configuration refers to the client secret or signing key as ${env:NAME} or ${vault:path:key}. The relay resolves them when it starts, and masks them in every log line.

Step 2 of 4

Login to the identity provider

The relay obtains an access token with the client credentials, JWT bearer or password grant, retrying with backoff if the provider is unavailable. It reports ready once it holds a token.

Step 3 of 4

Token added to every request

Each request your services send is relayed with the token added. Before the token expires it is renewed in the background, by refresh token or a new login, so no request waits.

Step 4 of 4

Nothing left behind

On shutdown the relay finishes in-flight requests and exits. The tokens existed only in memory, so nothing remains on disk to steal.

Security best practices

Harden the
environment too.

Production checklist

  • Inject credentials from a secrets manager or your platform's secret store, never the config file.
  • Serve HTTPS with tls, or put the relay behind a TLS-terminating proxy.
  • Set an apiKey so only your services can call the relay.
  • Run it as an unprivileged user with least-privilege access to its secrets.

Use cases

Wherever an API
needs a token.

Any service that calls an OAuth 2.0 protected API can hand the token work to OAUTH2Relay and keep credentials out of its own code.

Microservices

Run one relay per API as a shared service or a sidecar, so every service calls the API without its own token handling.

Kubernetes and containers

Credentials from Kubernetes Secrets, Vault or workload identity; probes, metrics and certificate reload included.

Serverless functions

Short-lived functions call a relay running as a service and get a ready token, instead of logging in on every cold start.

Partner and SaaS APIs

Payment, logistics and SaaS APIs that issue client credentials: one relay holds the token, with the secret kept in your vault.

Regulated industries

Finance and healthcare teams keep credentials in an audited secrets manager and tokens off disk, with every request logged.

Edge and on-premises

A single static binary with no database runs on small servers and gateways, and its tokens vanish on reboot.

Technical highlights

Configure with
environment variables.

Write ${env:API_CLIENT_SECRET} in the configuration and OAUTH2Relay reads the variable at startup, so the file itself never holds a secret. An unset variable stops the relay with a clear error.

  • Environment variables: export the credentials, then start the relay. How it works.
  • Secrets managers: AWS Secrets Manager, HashiCorp Vault and Azure Key Vault, re-fetched on a schedule for rotation. Secrets.
  • Flexible routing: one endpoint, a whole API, or allow-listed hosts chosen by the caller. Relay modes.
terminal
$ export API_CLIENT_SECRET='s3cr3t!'

$ cat config.json
{
  "port": 8080,
  "host": "127.0.0.1",
  "login": {
    "url": "https://auth.example.com/oauth/token",
    "grant_type": "client_credentials",
    "client_id": "my-service",
    "client_secret": "${env:API_CLIENT_SECRET}"
  },
  "relay": {
    "url": "https://api.example.com/v1",
    "headers": { "Authorization": "Bearer ${ACCESSTOKEN}" }
  }
}

$ oauth2relay --check-config --config config.json
config.json: configuration is valid

$ oauth2relay --config config.json
$ curl http://127.0.0.1:8080/orders   # relayed to /v1/orders with the token

Download

Version 2.1.0.
Free and open source.

Each archive holds the binary, the licence, the documentation and a hardened systemd unit. Verify the download against SHA256SUMS before installing it.

Installation guide   Upgrade notes

install on Linux
$ sha256sum -c SHA256SUMS --ignore-missing
oauth2relay_2.1.0_linux_amd64.tar.gz: OK
$ tar xzf oauth2relay_2.1.0_linux_amd64.tar.gz
$ sudo install -m 0755 oauth2relay_2.1.0_linux_amd64/oauth2relay /usr/local/bin/
$ oauth2relay --version
OAUTH2Relay version 2.1.0

Open source

Free to use.
Support when you need it.

  • Apache License 2.0: use, modify and run OAUTH2Relay in production, including commercially, at no cost.
  • Security fixes for the latest release. Report vulnerabilities privately to info@fijomi.com.
  • Commercial support and an enterprise edition for organisations are available from Fijomi Systems. Get in touch.

FAQ

Questions,
answered.

Yes. It is open source under the Apache License 2.0, so you can use it, change it and run it commercially at no cost. Commercial support and an enterprise edition are available from Fijomi Systems.

Keep them out of the configuration file. Reference environment variables with ${env:NAME}, injected by Kubernetes Secrets, systemd or your container platform, or fetch them from AWS Secrets Manager, HashiCorp Vault or Azure Key Vault. See Secrets.

The tokens are lost with it, because they only ever exist in memory. When the relay starts again it logs in with the credentials from your environment or secrets manager and gets a new token. Its readiness endpoint reports ready once it has one.

Any OAuth 2.0 token endpoint that supports the client_credentials, JWT bearer (RFC 7523) or password grant, including signed assertions with RSA, RSA-PSS and ECDSA keys as used by Google service accounts and Salesforce. Providers with their own login format can use a custom request. See Grant types.

Yes. In passthrough mode, the request path is appended to a base URL, so one relay covers a whole API. In parameter mode, callers pass the full target URL in a parameter, and it must point to a host in your allowed_hosts list. One relay uses one identity provider configuration. See Relay modes.

Yes, as a service your functions call. OAUTH2Relay is a long-running HTTP server, so run it in a container or on a VM, and point your functions at it. They then get a ready token on every call instead of logging in on each cold start.

Scrape /metrics with Prometheus and use /healthz and /readyz for liveness and readiness. The operations guide lists the alerts to set, such as failing token renewals and an expiring TLS certificate.

Contact us

Talk to
the team.

Questions about OAUTH2Relay, commercial support or the enterprise edition? Send us a message.

Keep tokens out of storage.
Start in minutes.