RBAC & OAuth
Per-Endpoint RBAC & Access Control
Control who can access each endpoint with role-based access control. Configure in the dashboard under Endpoint Settings → Access Control.
Client Management
Each endpoint can have its own set of authenticated clients. Clients support multiple auth methods simultaneously:
- Username & Password — Basic credentials with configurable password
- Static Token — API key or bearer token for programmatic access
- OAuth Subject — Linked to an external provider (Google, GitHub, Azure, Okta, Custom)
All credential changes are recorded in a credential audit trail (creation and updates tracked by type).
Invite Links
Invite a user by link (Endpoint Settings → Access Control → Invite by link, or the API):
- Optionally set the invitee's email, display name and role (without a role they get the endpoint's default roles; when the endpoint has no default role, a role is required)
- The link opens on the endpoint's own hostname:
https://<endpoint host>/_tunnel_auth/register?invite=... - The invitee chooses a username and password, or signs in with one of the endpoint's OAuth providers, and is signed in. With OAuth, the provider account's email must be the invite's email (and not reported unverified); an invite without an email is accepted with a username and password only
- The link works once, only on that endpoint, and expires after 72 hours by default (API: up to 1 year)
- The registration policy applies when the link is used: closed registration refuses it, Requires Approval creates the user pending, and email verification emails a confirmation link to the invite's address first. In Invite Only the invite is your approval: the user gets access right away (once they confirm their email, when that is required)
- The confirmation link works for 24 hours. A username that is already taken is refused before any email goes out
- One invite sends at most one confirmation email every 2 minutes and 5 a day. Past that the invitee sees Already sent — check your inbox: no new email is sent; they use the link they already have (or look in spam)
Registration Policy
Control how new users can register for endpoint access. Three modes:
| Mode | Behavior |
|---|---|
| Open | Anyone can register and get access |
| Invite Only | Only users with a valid invite link can register. The invite is the approval: they don't wait for an admin |
| Requires Approval | Users can register but must be approved by an admin |
Additional policy settings:
- Domain allow/block lists — Restrict registration (invites and OAuth sign-up) to specific email domains; domains match exactly, case-insensitively (a subdomain is a different domain)
- Email verification — Require email confirmation before access
- Password complexity — Enforce minimum length, uppercase, lowercase, numbers, special characters
- Default role — Role automatically assigned to new registrations
Sign-in protection
The endpoint's login page (/_tunnel_auth/login) and the Authorization: Basic header limit failed sign-ins; successful ones don't count. The limits are per endpoint and counted separately in each region. An IPv6 address counts as its /64, and an unknown username counts like a real one.
| Counted per | Limit | Then |
|---|---|---|
| Username + IP | 5 failures in 15 minutes | That username is blocked from that IP until the 15 minutes are up. A successful sign-in resets the count |
| IP (all usernames) | 20 failures in 15 minutes | That IP is blocked for 15 minutes |
| Username (all IPs) | 20 failures in 15 minutes | That username is blocked for 15 minutes |
A blocked attempt gets a 429 with a Retry-After header. On the login page it reads Too many failed sign-in attempts. Please try again in N minutes.
- Known devices — After a successful password sign-in over HTTPS, the login page sets the cookie
__Host-ngris_kd: this browser is a known device of that user on this endpoint for 30 days. A known device skips the per-IP and per-username limits, so password guessing from elsewhere, or other people on the same network, doesn't lock the user out of their usual browser. The username + IP limit always applies, and theAuthorization: Basicheader has no device exemption. Changing the user's password ends the exemption on every browser within seconds; each one becomes a known device again at its next successful sign-in. - Not affected — Visitors who are already signed in (their session keeps working), sign-in with the endpoint's OAuth provider (Google, GitHub…), and bearer tokens.
- If one of your users is blocked — There is nothing to unlock: the block ends on its own within 15 minutes. Meanwhile they can sign in with the endpoint's OAuth provider, if it has one, or from a browser they signed in on before (unless the failures were their own, from that network). In the traffic inspector these requests are 429s with the rule
endpoint_auth_login_limit_pair,_ipor_user(endpoint_auth_basic_limit_…for the Basic header). - Sign-ups — Invite and confirmation links that don't work (wrong, used or expired): after 10 from one IP within 10 minutes, that IP gets Too many attempts (429) for 10 minutes. Open sign-up through OAuth takes at most 20 new users per endpoint per hour; past that, new visitors see Sign-ups are paused for a moment — try again later, while existing users keep signing in.
An invited user who enters the right password before their access is ready is told what they are waiting for (403, not signed in). A wrong password always gets the usual The username or password you entered is not valid.
- Awaiting approval — Requires Approval mode: activate the user (Activate User in the user's menu, or the status API).
- Check your email — Confirm your email first: we sent a link to j***@example.com. The user opens that link; no new email is sent.
- Link unavailable — Your confirmation link has expired — ask the site owner for a new invite. Activate the user, or delete them and send a new invite (an endpoint can't have two users with the same email).
Client Sessions & Login History
- View all active sessions per client (with optional expired sessions)
- Revoke individual sessions or revoke all sessions at once
- View login history (last 50 events by default, configurable limit)
Client Metadata Forwarding
Attach custom key-value metadata to clients. Metadata is forwarded downstream as HTTP headers and included in request logs, enabling backend services to identify clients without additional lookups.
Bulk Operations
Select multiple clients via checkboxes and perform bulk delete operations to clean up inactive or unwanted accounts.
| User | Status |
|---|---|
|
M
Maria Example
maria
|
active
|
|
C
CI deploy
ci-deploy
|
active
|
|
A
Acme Ops Bot
ops-bot
|
pending
|
OAuth Provider Configuration
Configure per-endpoint OAuth providers for delegated authentication. Set up in the dashboard under Endpoint Settings → OAuth / SSO.
Supported Providers
- Google — OAuth 2.0 with Google identity
- GitHub — OAuth 2.0 with GitHub accounts
- Azure AD — Microsoft identity platform
- Okta — Enterprise SSO via Okta
- Auth0 — Auth0 identity platform
- Custom — Any OIDC-compatible provider
Provider Configuration
| Field | Description |
|---|---|
| Client ID | OAuth client ID from the provider |
| Client Secret | Encrypted client secret (stored encrypted at rest) |
| Auth URL | Authorization endpoint URL |
| Token URL | Token exchange endpoint URL |
| User Info URL | User info endpoint for fetching identity |
| Scopes | OAuth scopes (e.g., openid email profile) |
| Identifier Field | JSON field from user info to use as unique identifier (e.g., email, sub) |
| OIDC Issuer | Optional. When set (e.g. https://accounts.google.com), the edge cryptographically verifies the id_token (signature, exp, iss, aud) instead of trusting the user-info endpoint. |
| JWKS URL | Optional. Signing-key endpoint — discovered from the issuer's .well-known/openid-configuration if left blank. |
| Enabled | Toggle provider on/off |
The dashboard displays the Redirect/Callback URL for easy configuration in your OAuth provider's settings. Each provider type shows a guided setup card with provider-specific instructions.
id_token at the edge.