Base IdP

Base IdP

Getting Started

Create an App

Register your application in Square Experience Cloud to get a client id and, if needed, a secret.

Every Base IdP integration starts the same way: you register an app in Square Experience Cloud. The registration is where Base IdP stores everything about your app — redirect URIs, scopes, audience, allowed auth methods, the display name on the consent screen. After this step you have a client id (and possibly a secret) to hand to the SDK. From that point on the SDK reads the rest of the configuration from the registration at runtime.

You do this once per environment per app. Production gets a production registration. Local development gets its own. Staging gets its own. The credentials are not interchangeable.

Open Square Experience Cloud

Go to Square Experience Cloud and click Create App. You will be asked for a display name, the application type, and the redirect URIs your app will use.

The display name is what users see on the consent screen and in audit logs. Pick something a real user would recognize, not an internal code name.

Pick the application type

The application type tells Base IdP what kind of client you are registering, which in turn decides whether you get a secret.

TypeWhat it isGets a secret?
nativeiOS, Android, desktop, Electron — anything that runs on a user's device.No. Public client, PKCE only.
spaSingle-page apps running in a browser.No. Public client, PKCE only.
webServer-rendered apps that exchange codes on a backend.Yes. Confidential client.
machineBackend services that authenticate as themselves.Yes. Confidential client.

A common mistake is registering a mobile app as web because it has a companion server. The mobile app itself is native. The companion server, if it exchanges codes or verifies tokens, is web (or it does not need its own registration at all if it only verifies).

Set the redirect URIs

The redirect URI is where Base IdP sends the user after a successful login. It must match exactly what your app passes in the authorize request. No wildcards. No trailing-slash differences. No http vs https confusion.

Mobile redirect URIs

For a mobile app, the redirect URI uses a custom URL scheme that your app registers with the OS. The scheme is whatever you want, as long as it is unique to your app.

myapp://auth/callback
twende-partners://auth/callback
zhio-driver://oauth/return

You then register the scheme in ios/Runner/Info.plist and android/app/src/main/AndroidManifest.xml (or the equivalent for your toolkit) so the OS knows to hand the URL back to your app.

Web redirect URIs

For a web app, the redirect URI is a normal HTTPS URL on your domain.

https://app.example.com/api/auth/callback
http://localhost:3000/api/auth/callback

Register all of them — production, staging, and every local-dev host you use. Base IdP will only redirect to one that is in the list.

Copy your credentials

When the registration is saved, you get back:

  • client_id — public. Safe to ship in a frontend bundle. This is the value you paste into BASE_IDP_CLIENT_ID.
  • client_secret — only for web and machine apps. This value must never leave a server. If it ends up in a Git repo or a mobile bundle, rotate it immediately.
.env (confidential server)
BASE_IDP_CLIENT_ID=sq_live_yourapp_abc123
BASE_IDP_CLIENT_SECRET=sqk_3b7157c3d69f11a4af17d6c955ae31fd1fe3183e10b329c1ef4220c3badc0c18
.env (public frontend)
BASE_IDP_CLIENT_ID=sq_live_yourapp_abc123

Credentials come from the console, never invented

Never hardcode, generate, or guess a client_id or client_secret. They are issued by Base IdP at registration time. A secret in a public bundle is a leaked secret — rotate it the moment you realize.

Verify the registration is live

Once the registration is saved, you can verify Base IdP knows about it by running the CLI's test command against your client id.

npx base-idp test --client-id sq_live_yourapp_abc123

If the registration is active you see:

Testing Base IdP connection to https://authlayer.squareexp.com...
  healthz: 200 OK
  discovery: 200 OK
  client-config: 200 OK

IdP is reachable.

A client-config: 404 here means the client id does not resolve. A 403 means the app is registered but disabled. Both are registration problems, not code problems — fix them in the console before you write a line of integration.

What you do not need to copy

Once registered, Base IdP knows your app's settings and serves them from the client-config endpoint at runtime. You do not paste any of this into env.

Resolved at runtimeSource
IssuerSDK default, override only for local dev
AudienceCarried in the token, resolved from client config
Allowed scopesPOST /v1/client-config
Allowed redirect URIsPOST /v1/client-config
Allowed auth methodsPOST /v1/client-config
Public signing keysGET /v1/keys/paseto-v4-public

If a tutorial or README anywhere asks you to put an issuer URL, an audience string, or a list of scopes into a .env file, that document is out of date. None of those values belong in your repository.

Editing the registration later

When you need to add a new redirect URI (because you ship a new local port, or deploy to staging) you go back to the console and add it. There is no code change in your app. The SDK re-fetches the client config the next time it needs to.

This is also how you change scopes, swap the consent-screen logo, or rotate the secret. Always in the console, never in code.

Where to go next

On this page