Skip to content
On this page

Admin guide

How to set up a new client application, and what to hand the team integrating it.

Set up a new client

#

Every application that wants "Sign in with Giftem" needs a tenant (the company/organization owning the login) and an application (one OAuth client) under it. Provisioning a tenant creates a sandbox twin automatically — but the application itself is not mirrored, so you create it once under the sandbox tenant and, separately, again under the live tenant when the integration is ready to launch. Each gets its own client ID and secret; they're never shared. A tenant's name can be edited any time from its page (typo fixes, a rebrand) — its slug cannot, since relying parties receive it as the tenant claim and it's set once at provisioning.

  1. 1. Log into the admin panel and go to Tenants. Pick the tenant the new client belongs to, or provision a new one if it doesn't exist yet — this also creates its sandbox twin automatically.
  2. 2. Open the sandbox tenant (named <slug>-sandbox in the tenant list) to hand out sandbox credentials first — it's the only place plain http:// redirect URIs are allowed, and only on localhost, 127.0.0.1 and .test / .localhost hosts (localhost and .localhost always stay on the integrator's own machine; a .test name is reserved but is resolved by their own DNS, so tell them to give it a hosts-file entry), so it's what integrators should build and test against before anything goes live.
  3. 3. New application — name it, and set the redirect URI to the exact callback URL the client application will handle the response on (e.g. http://localhost:8080/auth/onelogin/callback for a local dev server).
  4. 4. Copy the one-time reveal. The client ID, secret, discovery URL and a ready-to-paste .env block are shown once — hand that block to whoever is integrating the client. If it's lost, rotate the secret — choose how long the old one keeps working (immediately, or a window up to 7 days, so every server has time to switch), then revoke it early once they have, or let it expire. The application page shows when the previous secret was last used — watch that line and revoke it once it stops moving. After the reveal, you can prove the setup end to end — real login, tokens, userinfo — from the application's own Try it page before handing the credentials over.
  5. 5. Repeat under the live tenant when the integration is ready to go live — a new application, a new redirect URI (https:// only), a new client ID/secret pair. Promoting from sandbox to live is a config change on the client's side (swap the credential block), not a code change — see the integration guide.

The new-application form also asks for a type. Confidential (the default) is for an application with a server that can keep a secret: it is issued a client secret, shown once in the reveal. Public is for an application that cannot keep a secret, such as a native mobile app: it is issued no secret (the reveal has no secret to show) and relies on PKCE alone, which every application uses regardless of type. The integration guide describes the confidential, server-side flow, so confirm the type with the team before creating a public application.

Go to admin panel

The admin panel also has four screens for day-to-day oversight: Users (accounts across tenants, with verification and lockout state, and which sign-in methods each account has — password, Google, Facebook). Opening a user (Manage) shows their full state and sign-in history and, for a full admin, six actions on a stuck account: force logout, unlock, resend verification, mark verified, suspend/unsuspend, and delete (delete requires the account to already be suspended, plus your password and the typed email). Everything else stays read-only: Audit log (every administrative change, with before/after detail), Auth events (the sign-in forensic trail), and Sandbox mail (emails captured from test tenants — including the codes testers need, since sandbox mail is never actually delivered). The Users and Auth events searches also accept a user's ID (the sub claim a relying party's logs or a support ticket would quote) — paste it in as-is, by name, email or user ID. A System page rounds these out with a read-only deployment snapshot — the last scheduled cleanup run, mail/SMS configuration and recent failures, passkey/proxy/signing-key status, and pending admin invitations — presence and counts only, never a credential value.

Google/Facebook sign-in is one set of provider credentials for every tenant (server configuration, not something you set per tenant here) — see the integration guide for what a relying party needs to know about it (nothing).

Live and test activity are never mixed in the user and log views. Users, Audit log and Auth events open on Live; a switch at the top changes the scope to Sandbox (test tenants), and on the two logs to Admin & system (admin sign-ins and other events not tied to a tenant). Sandbox log entries and captured sandbox mail are kept for 30 days by default, then deleted; live entries are not.

Admins

#

Two roles: Admin (full access — provision, rotate, suspend, manage other admins) and Viewer (read-only — every screen in the panel, no mutation). Adding an admin is always an invitation, never direct creation: Admins → Invite admin emails a one-time setup link (72 hours) to the address; the account is created only once they open it and choose a password, so no password ever travels by mail. Admins are disabled, never deleted — their audit trail stays intact. A dashboard banner appears when only one full admin is active, prompting a second invite.

A colleague locked out of their password: another admin uses Send password reset on the Admins page (a 60-minute one-time link, password-confirmed). If you're the only admin and you're locked out, or the box has none yet, use SSH and the console: php artisan admin:recover <email> (add --new-email= if the mailbox itself is lost) or php artisan admin:create <email> [--role=viewer] for the very first admin on a fresh box — each prints a one-time setup link, nothing else. There's deliberately no self-service "Forgot password" on the admin login: with email-OTP as the second factor, a self-service reset would make mailbox access alone sufficient for a full session.

Developer accounts

#

A developer account is for a person on an integrating team, not an admin. It belongs to exactly one live tenant and reaches that tenant's sandbox twin automatically; it has no access to this admin panel, to other tenants, or to live end-user data (it does read that sandbox twin's captured test mail, see below). It is a separate sign-in, at /developer.

Invite one. Open the live tenant's page (Tenants, then the tenant — a sandbox tenant's page has no Developers card) and use Invite a developer: enter their email, press Send invite and confirm with your own admin password in the dialog that opens (the same confirmation as Resend and Disable). A one-time setup link (72 hours) is emailed to them; the account is created only once they open it and choose a password, so no password ever travels by mail. Until then the invitation is listed as pending, where you can Resend it (a fresh link, password-confirmed) or Revoke it. Inviting an address that already has a developer account is refused, and a newer invitation to the same address replaces the older one. Only full admins can invite; a viewer sees the list read-only. Point the developer at the developer guide: it explains signing in and everything they can and cannot do from their side.

What developers can and cannot do. They sign in with their password and an emailed code every time (there is no “remember this device”). They can see the applications registered for their tenant and its sandbox (name, client ID, type, status, redirect URIs — never a secret), read the sandbox inbox of captured test sign-in codes, and add and remove redirect URIs on their sandbox applications within the limits below, and rotate the client secret of a sandbox application themselves (their own password, then the new secret is shown to them once and the old one keeps working for 24 hours unless they pick another window; at most 5 rotations an hour, recorded in the Audit log as application.rotate_secret with the developer as the actor, no email). Their live applications are read-only for them, with one exception: they can ask for a redirect URI to be added or removed, and nothing changes until you approve it (see Reviewing developer requests). Rotating a live application's secret is done by you, unless you switch on developer live secret rotation for that tenant (off by default). They cannot create, edit or suspend anything, cannot see another tenant, and cannot reach this admin panel.

Approved origins — a one-time judgment. On a sandbox application's edit page, the Developer-approved origins card lists the https://host (or https://host:port) origins a developer may register redirect URIs on. localhost, 127.0.0.1 and any .test or .localhost host on any port are always allowed and need no entry — that free tier covers local development, so the list is only for something like the team's staging site. Approve an origin once, after deciding you trust whoever controls that host: from then on any path on it can be added without you, which is the point. Entries are exact (no wildcards, no paths, https only, at most 10, never this OneLogin server itself, and never a different port on its host: that is not blocked for you, but browsers share cookies across the ports of one host, so don't approve one); changing the list asks for your password and is recorded in the Audit log (application.update_developer_origins, with the before and after lists). Un-approving an origin stops new URIs on it; URIs already registered stay until someone removes them.

What developers can add, and what you can see. Each developer change is one exact URI, added or removed, confirmed with the developer's own password, capped at 20 URIs per application and 20 changes an hour. The reserved Try-it return address cannot be removed by a developer. Every change is an Audit log row (application.developer_update_redirect_uris, actor dev: <name>, with the full before and after lists); no email is sent for sandbox changes. Two developers changing the list at once never lose each other's change, and a developer change (or an approval, below) is always applied to the latest saved list. The Allowed redirect URIs textarea saves the whole list, so it is guarded the same way: the form remembers the list it was opened on, and if that list changed while the page was open (a developer request approved, another admin's edit, a Try-it run) saving a list change is refused with a message and nothing is written, before your password is even asked. Reload the page and apply your edit again. Renaming an application or changing its first-party setting with the list left alone is not affected.

Reviewing developer requests (live applications). A developer asks for one exact redirect URI to be added or removed on a live application, confirmed with their own password. Every active full admin gets an email, and the request waits in the Pending developer requests card on that application's edit page (the tenant page shows a pending-count badge next to the application). Viewers see the card read-only. A request lapses after 14 days if nobody decides it, an application can have at most 10 open requests, and a developer can cancel their own pending one. Nothing is applied until you decide:

  • Approve asks for your admin password, like editing the redirect URIs yourself. It applies exactly that one change to the application's latest saved list, so the approval never overwrites a change an admin or developer saved a moment ago, after re-checking the address against the textarea's rules (https only, no fragment, no username or password, never this server itself) plus no wildcards, no spaces and a plain host name, and against the portal's limit of 20 URIs per application (your own textarea edits are not capped; a developer's add is). If the address was already registered (or a removal is already gone), the request simply closes as approved and says nothing changed. If two admins click at once, it is applied once; if an approval is refused, the request stays pending and you can reject it instead. An Allowed redirect URIs form you had open before the approval is refused when you save it (see above), so the approved change is never silently dropped.
  • Reject needs no password and takes an optional short note (up to 200 characters, shown to the developer as plain text). The list is left as it is.
  • Either way the developer is emailed the decision, and every step is an Audit log row: application.uri_change_requested (actor dev: <name>), application.uri_change_approved (with the exact before and after lists), application.uri_change_rejected and application.uri_change_cancelled. The requests themselves are housekeeping: decided or lapsed ones are deleted after 90 days (the Audit log rows stay).

Developer live secret rotation (a per-tenant switch, off by default). On a live tenant's page, the Developer live secret rotation card turns on a standing permission: that tenant's developers can rotate the client secret of the tenant's live confidential applications themselves, without asking you. Turn it on only for a team you trust with production credentials, and only when they have asked. Turning it on or off asks for your admin password (full admins only; viewers see the state) and is an Audit log row (tenant.developer_live_rotation_enabled or …_disabled, with the before and after value). A sandbox tenant never has the switch, and sandbox rotation is not affected by it.

  • What the developer does. They enter their portal password and pick how long the old secret keeps working (including Now, which cuts the old secret off at once). Nothing is rotated yet: OneLogin emails a 6-digit code to them, and only when they enter it (within 10 minutes, five tries, once) is the secret rotated and shown to them once. You never see the new secret, and it is never stored in the clear. At most 5 rotations an hour per developer, and a wrong code or a refused attempt never uses that allowance.
  • What you get. The moment a live secret is rotated, every active full admin is emailed (the application, tenant, developer, time, IP address and when the old secret stops working, never a secret). Viewers and disabled admins are not emailed. If the mail cannot be sent the rotation still stands: the Audit log row application.rotate_secret (actor dev: <name>, environment live, with only the grace expiry) is the durable record.
  • If it was not expected. Treat the developer account as compromised: disable it from the tenant's Developers card, suspend the application if it must be cut off at once, then rotate the secret from the application's edit page. The previous secret can be revoked straight away there.
  • Turning it off is immediate. A rotation a developer has already started (waiting for their code) will not complete, and a new secret not yet shown to them is discarded. Live redirect URIs are unaffected: they still need your approval, and developers still cannot create, edit or suspend anything. A suspended application cannot be rotated by a developer.

Removing a redirect URI is not revocation — suspend the application instead. Removing a URI (by request or by hand) stops new sign-ins from returning there, but it does not cancel authorization codes that were already issued (they stay valid for up to 10 minutes) or tokens that were already issued. If a live application has to be cut off at once, suspend the application (its Suspend button): that is checked at both the authorize and the token step.

Stricter redirect-URI rules, for everyone. Because the developer portal shares the admin panel's validation, these now apply to your own edits too: a redirect URI may not contain a fragment (#…), may not contain a username or password in the address (https://name@host/…), and may not point at this OneLogin server itself (apart from the reserved Try-it return address). Applications already saved with such a URI keep working; the next time you save that application's edit form (even for a name change) it will ask you to remove the URI first.

Disable and reset. Disable (on the same card, password-confirmed) signs a developer out on their next request and stops them signing in; the account is kept, never deleted, so the audit trail stays intact, and Enable turns it back on. There is deliberately no self-service “Forgot password” on the developer login: if a developer is locked out, use Send reset on their row (a 60-minute one-time link, password-confirmed). Every one of these actions is recorded in the Audit log, under the Admin & system scope.

The portal is off until you switch it on. The developer portal is controlled by the server setting DEVELOPER_PORTAL_ENABLED, which is off by default; while it is off, every /developer page is simply not there. The Developers card still shows who is invited and lets you disable or revoke, but invite, resend and reset will not send a link that could not work yet. Developer sign-in codes and invitations are real email (never captured as sandbox mail), so turn it on only on a deployment where email actually delivers.

Sandbox vs. live

#

There's no separate sandbox domain or environment to point at — it's the same OneLogin instance, same issuer, same endpoints either way (see the integration guide for those). What changes is which tenant, and which application's client ID/secret, a request resolves to.

Aspect Sandbox Live
Tenant auto-created twin, <slug>-sandbox the tenant itself
Application / credentials its own application, own client ID + secret a separate application, separate client ID + secret
Redirect URI http:// allowed on localhost, 127.0.0.1, .test and .localhost hosts https:// required
Issuer & endpoints identical — see the integration guide
Use for integration development, local/automated testing real end users

An integrator has no admin account, so they can't open Sandbox mail to read the sign-in codes their test users receive. To let them see those codes themselves, open the sandbox tenant's own page (the <slug>-sandbox row, not the live tenant) and use Enable developer inbox in its Developer inbox card. You confirm your password, and the page shows a private link once — copy it and send it to the integrating team over a private channel. Anyone holding the link can read every message captured for that one sandbox tenant (and nothing else: no admin screens, no other tenant, no live data), and the link expires after 90 days by default. If the link leaks, choose Rotate link: the old one stops working at once and a new one is shown once. When the integration goes live, choose Disable. Because the link exposes the whole tenant's captured mail, give an outside team its own tenant rather than a sandbox shared with other testers. Full admins can enable, rotate and disable; viewers see the card's status only.

What to hand an integrator to get them started: the sandbox application's one-time .env block (issuer, client ID, client secret, redirect URI) from step 4 above. Nothing else differs from a live integration — the same code points at either, only the four values in that block change. Point them at the integration guide, whose public Try-it console lets them call the endpoints with those sandbox credentials straight from the docs (it refuses live credentials).