Skip to main content
connic
Apps

Sign-in

Choose who can open an app: anyone, members of your connic project, or people from your own identity provider. Set it in code or in the dashboard.

Last updated

Modes

ModeWho can open the app
publicAnyone with the link. There is no sign-in.
connicMembers of the project, with their connic account. Optionally limited to some permission groups.
oidcPeople your OpenID Connect provider signs in, such as Entra ID, Okta, or Google Workspace. Optionally limited to some email domains or groups.

On apps that require sign-in, connic checks the session before it serves any file and before it forwards any connector or data request. A new app without sign-in settings in code or in the dashboard uses connic accounts and lets every project member in.

Code or dashboard

Set sign-in in the auth block of apps/<key>.yaml, or leave auth out and set it on the app's Settings tab in the dashboard, under Sign-in. When the file declares auth, the file wins: the dashboard shows the settings with an In code badge and doesn't let you change them. connic MCP's update_app follows the same rule.

When a deploy stops declaring auth, the app keeps its last sign-in settings, including the OIDC client secret, and the dashboard manages them from then on. A deploy only changes who can open an app when the file says so.

Any change to the sign-in settings that apply, in code or in the dashboard, signs everyone out of the app.

connic accounts

apps/portal.yaml
auth:
  mode: connic
  groups: [Support, Admin]     # optional; without it, every project member

Visitors sign in with their connic account and must be members of the project. With groups, they also need one of those permission groups; the project owner can always open the app. Every group must exist in the project, or the deploy fails. In access rules and in the run context, user.id is the visitor's connic user ID and user.groups lists their permission groups in the project.

connic accounts suit internal tools and staging environments. For your customers' or partners' employees, use their identity provider.

Your identity provider

With oidc, visitors sign in with any OpenID Connect provider. connic runs the authorization code flow with PKCE and sends the client secret with HTTP Basic authentication (client_secret_basic).

apps/portal.yaml
auth:
  mode: oidc
  issuer: https://login.microsoftonline.com/${ENTRA_TENANT_ID}/v2.0
  client_id: ${PORTAL_CLIENT_ID}
  client_secret: ${PORTAL_CLIENT_SECRET}
  allowed_domains: [example.com]
  allowed_groups: [support]
  groups_claim: groups
FieldTypeStatusDescription
modestringRequiredpublic, connic, or oidc. Dashboard: Who can open the app.
groupsstring[]Optionalconnic only. Permission groups that may open the app. Empty lets every project member in. Dashboard: Permission groups.
issuerstringOptionaloidc, required. The provider's issuer URL, starting with https://. connic reads <issuer>/.well-known/openid-configuration, and the issuer named there must match. Dashboard: Issuer.
client_idstringOptionaloidc, required. Dashboard: Client ID.
client_secretstringOptionaloidc, required. In a file, a ${NAME} reference to a Variable. In the dashboard, write-only: leave it empty to keep the stored secret. A changed issuer or client_id needs the secret again. Dashboard: Client secret.
allowed_domainsstring[]Optionaloidc. Email domains that may sign in, such as example.com. Empty allows every email. The email comes from the email claim, or from preferred_username when that is an email address. A visitor whose email the provider marks as unverified has no email and doesn't pass. Dashboard: Allowed email domains.
allowed_groupsstring[]Optionaloidc. The visitor needs at least one of these groups in groups_claim. Empty allows every group. Dashboard: Allowed groups.
groups_claimstringOptionaloidc. The ID token claim that lists the visitor's groups; it becomes user.groups. Dashboard: Groups claim.Default: groups
scopesstring[]Optionaloidc. Extra scopes. connic always asks for openid, profile, and email, and for offline_access when the provider supports it. Dashboard: Extra scopes.

Fields of another mode are rejected, so a connic app can't set issuer.

Set up the provider

  1. Register a web application with a client secret at the provider.

  2. Store the client ID and secret as Variables of each environment and reference them in auth, then deploy. Or choose Your identity provider on the app's Settings tab, fill in the fields, and click Save changes.

  3. Copy the Redirect URI from the app's Settings tab and register it with the provider. It is the same for every app.

connic checks the ID token's signature, audience, issuer, and nonce. When the token says email_verified: false, connic ignores the email: user.email is null, and a non-empty allowed_domains turns the visitor away.

Claims in rules

user.claims holds the ID token's claims about the visitor, such as a department or tenant claim, for access rules. connic leaves out the token's own fields, such as iss, aud, exp, and nonce, and keeps up to 8 KB of claims, smallest first. Claims aren't part of /_connic/me or of context["end_user"].

Sessions

After sign-in, the browser holds a session cookie for the app's host. connic renews it every 10 minutes and checks access again each time: project membership and permission groups for connic accounts, and for identity providers the allowed email domains and groups. When the provider issues refresh tokens, connic asks the provider on every renewal, so removing someone there takes effect within minutes. Without refresh tokens, it takes effect when the session ends.

A session ends after 12 hours, on sign-out, or when the app's sign-in settings change. The default URL and a custom domain each have their own sessions.

Without a valid session, page loads redirect to /_connic/login and come back to the same path after sign-in. Every other request, including connector calls and the data API, gets 401 with {"error": "Sign-in required"}. When the app gets a 401, send the visitor to /_connic/login?return=<path>. The return path must stay on the app's own host; anything else, including paths with control characters or backslashes, returns to /.

session.js
if (response.status === 401) {
  location.assign(`/_connic/login?return=${encodeURIComponent(location.pathname + location.search)}`);
}

Sign out

Link to /_connic/logout. It ends the session and shows a page with a link to sign in again. The visitor stays signed in at their identity provider.

Public apps

Public apps have no sign-in, and /_connic/login redirects to /. With the app's first data API or connector request, connic stores a random secret in a cookie that lasts a year and derives a visitor ID from it, different for each app. The ID becomes user.id in access rules and end_user.id in runs. Knowing a visitor's ID doesn't let anyone act as them. Clearing cookies gives a new ID, so it identifies a browser, not a person. Until the cookie is set, every request gets a new ID, so on first load let one request such as GET /_connic/me finish before the app sends others in parallel. See Public visitors for rules on public apps.

Cookies

connic sets these cookies on the app's host. Each is host-only, Secure, HttpOnly, and SameSite=Lax.

CookiePurposeLifetimeWhen it's set
__Host-connic_app_sessionKeeps a signed-in visitor's session.12 hoursApps with sign-in: at sign-in, and again when connic renews the session. Sign-out deletes it.
__Host-connic_app_loginTies the return from sign-in to the browser that started it.10 minutesApps with sign-in: when sign-in starts. Deleted once sign-in succeeds.
__Host-connic_app_visitorHolds the random secret connic derives a public visitor's ID from.1 yearPublic apps: with the app's first data API or connector request. Pages and files never set it.

When sign-in fails

A failed sign-in shows a Sign-in didn't work page with one of these messages and counts as a failed sign-in in the app's stats.

MessageCause
Your account doesn't have access to <app>.The visitor isn't allowed in: not a project member or not in one of the permission groups, or an email domain or group the app doesn't allow, including an email the provider marks as unverified.
The app's sign-in provider can't be reached. Try again later.connic couldn't load the issuer's discovery document or reach its token endpoint.
The app's sign-in provider is misconfigured.The discovery document names a different issuer than issuer.
Sign-in was rejected by the provider. Try again.The provider refused the token request, for example because the client secret is wrong.
The sign-in response couldn't be verified. Try again.The ID token's signature, audience, issuer, or nonce didn't match.
Sign-in was cancelled. Open the app again to sign in.The visitor cancelled at the provider, or the provider returned an error.
This sign-in link expired. Open the app again to sign in.More than 10 minutes passed during sign-in, or the link was used before.