Guides
Run a standalone identity server
Configure SqlOS as a dedicated auth host for several web, mobile, CLI, and API surfaces.
Standalone SqlOS adds a control plane: multiple clients, assignments, headless UI routing, and resource API validation. Start with single-application setup unless you already have more than one app surface.
By the end of this guide you will have:
Register SqlOS in the ASP.NET host that will act as the identity server.
using Microsoft.EntityFrameworkCore;
using SqlOS.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ExampleAppDbContext>(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
builder.AddSqlOS<ExampleAppDbContext>(options =>
{
options.DashboardBasePath = "/sqlos";
var auth = options.AuthServer;
auth.Issuer = "https://auth.example.com/sqlos/auth";
auth.PublicOrigin = "https://auth.example.com";
auth.DefaultAudience = "https://api.example.com";
});
var app = builder.Build();
app.MapSqlOS();
app.Run();The public issuer must be stable. Resource APIs validate tokens against this issuer.
Give every app surface its own client ID and redirect URI.
builder.AddSqlOS<ExampleAppDbContext>(options =>
{
var auth = options.AuthServer;
auth.SeedBrowserClient(
"customer-portal",
"Customer Portal",
"https://app.example.com/auth/callback");
auth.SeedBrowserClient(
"admin-console",
"Admin Console",
"https://admin.example.com/auth/callback");
auth.SeedBrowserClient(
"mobile-app",
"Mobile App",
"sqlos-mobile://auth-callback");
auth.SeedCliClient(
"support-cli",
"Support CLI",
"https://api.example.com",
"openid",
"profile",
"email",
"offline_access");
});Client IDs identify the app asking for login. Audience identifies the resource API that should accept the access token. Two clients can use the same audience and still have different application access policy.
Use hosted AuthPage when a shared login page is acceptable.
Use headless when each frontend should own the login UI while SqlOS owns OAuth state.
auth.UseHeadlessAuthPage(headless =>
{
headless.BuildUiUrl = ctx =>
QueryHelpers.AddQueryString(
"https://app.example.com/auth/authorize",
new Dictionary<string, string?>
{
["request"] = ctx.RequestId,
["view"] = ctx.View,
["email"] = ctx.Email,
["pendingToken"] = ctx.PendingToken,
["ui_context"] = ctx.UiContext?.ToJsonString()
});
});See Headless Auth and Hosted vs Headless.
Start with open access for the customer-facing app. Restrict sensitive surfaces.
curl -X POST https://auth.example.com/sqlos/admin/auth/api/applications/admin-console/access-mode \
-H "Content-Type: application/json" \
-d '{ "accessMode": "selected_users_groups_roles" }'Allow tenant admins for one organization:
curl -X POST https://auth.example.com/sqlos/admin/auth/api/applications/admin-console/assignments \
-H "Content-Type: application/json" \
-d '{
"principalType": "role",
"organizationId": "org_123",
"roleKey": "admin",
"access": "allowed",
"reason": "Tenant admins may use Admin Console"
}'Explain a decision:
curl "https://auth.example.com/sqlos/admin/auth/api/applications/admin-console/access/check?organizationId=org_123&userId=usr_123"Resource APIs should validate issuer, signature, expiry, and audience. They should not rely on application access checks alone.
app.UseSqlOSAccessTokenValidation(options =>
{
options.ExpectedAudience = "https://api.example.com";
});Use FGA or app policy after token validation when the API needs row-level or resource-level authorization.
Use the SDK services for flows that are not just browser redirect login.
var invite = await authService.CreateEmailInvitationAsync(
new SqlOSCreateEmailInvitationRequest(
organizationId,
email: "alex@example.com",
role: "admin",
clientId: "admin-console",
redirectUri: "https://admin.example.com/auth/callback"),
httpContext,
ct);Open /sqlos/admin/auth, confirm all expected clients exist, and check their access modes.
Use Customer Portal, Admin Console, mobile callback, and CLI/device flow separately.
Use the access check endpoint before and after revoking an assignment.
Call the resource API with a token minted for the correct audience and with one minted for the wrong audience.
Tables for clients, access modes, assignment targets, endpoints, and enforcement points.
Assign applications to organizations, users, groups, and roles.
Owned apps, CLI clients, CIMD, and DCR paths.
AuthService, admin service, OTP, invitations, device flow, and token validation.