Getting Started
Choose the shortest SqlOS path for your .NET application.
net9.0)For a typical .NET B2B SaaS product you have one ASP.NET Core host, one EF Core DbContext on SQL Server or PostgreSQL, and one product that users sign in to. builder.AddSqlOS<TContext>(…) describes that product once and SqlOS derives the protocol consequences — auth routes, JWT schemes, metadata documents, client registration, seeds. Lock application APIs with RequireAuthorization(). If you expose MCP, set app.Mcp and map Microsoft's SDK yourself.
builder.AddSqlOS<AppDbContext>(
db => db.UseSqlServer(connectionString), // or db.UseNpgsql(connectionString)
options =>
{
options.UseSingleApplication("Acme", app =>
{
app.Origin = publicOrigin; // everything else derives from this
app.Api = "/api"; // resource id {Origin}/api — scheme audience + PRM
app.Mcp = "/mcp"; // resource id {Origin}/mcp — map the MCP SDK yourself
app.Brand(page => page.PrimaryColor = "#0f172a"); // hosted sign-in colors, logo, copy
// app.Headless("/auth/authorize"); // ...or your own sign-in UI instead of the hosted pages
app.Authorization(fga => fga // your permission model, reconciled at startup
.ResourceType("project", "Project")
.Permission("PROJECT_READ", "Read projects", "project")
.Role("project_viewer", "Viewer").Can("PROJECT_READ"));
});
options.Dashboard.AuthMode = SqlOSDashboardAuthMode.Password;
options.Dashboard.Password = dashboardPassword;
});Every line is optional except Origin. Start with Origin alone and add lines as the product needs them; nothing else changes.
| Option | Default | What SqlOS does with it |
|---|---|---|
app.Origin | required | Public origin of your app. Issuer ({Origin}/sqlos/auth), redirect URI ({Origin}/auth/callback), and audiences derive from it. |
app.Api = "/api" | off | Resource id {Origin}/api: default SqlOS JWT scheme audience, first-party client audience, and /.well-known/oauth-protected-resource. Lock your routes with RequireAuthorization(). Protect an API |
app.Mcp = "/mcp" | off | Resource id {Origin}/mcp: scheme/policy SqlOS.Mcp, a distinct audience, its own protected-resource document, and portable-client registration (CIMD + resource indicators). The host maps Microsoft's MCP SDK and calls RequireAuthorization("SqlOS.Mcp"). MCP server |
app.Brand(page => …) | Sign in to {Name} | Brands the hosted login, signup, OTP, MFA, and consent pages. Same options as AuthServer.SeedAuthPage. Branding |
app.Headless("/auth/authorize") | hosted pages | Switches to your sign-in UI: SqlOS redirects browser interaction to {Origin}/auth/authorize with the standard request, view, email, pendingToken, mfaToken, … parameters that @sqlos/headless reads. Same as AuthServer.UseHeadlessAuthPage. Custom login UI |
app.Authorization(fga => …) | none | Declares resource types, permissions, and roles; reconciled idempotently at startup. Same as Fga.Seed. Model your FGA |
app.AllowedScopes, ClientId, RedirectPath, RedirectUris, AllowNativeHeadlessAuth, EnablePasswordSignup, EnabledCredentialTypes | sensible | Fine-tuning of the single first-party PKCE client SqlOS seeds for you. All defaults |
options.Dashboard.AuthMode / Password | development-only | Who may open /sqlos. Set Password (from secrets) before anyone else can reach the host. |
Sign-in methods — passwords, email OTP, magic links, social login, SAML, MFA — are options.AuthServer seeds or dashboard settings, not code changes. Turn them on when you need them: Password · Email OTP · Social OIDC · SAML · MFA.
The hosted pages are the default and need nothing. When your product wants to own every screen, keep the same call and add one line:
app.Headless("/auth/authorize"); // your page at {Origin}/auth/authorize drives login, signup, OTP, MFA, consentYour frontend then talks to a typed state machine (npm install @sqlos/headless) while SqlOS still owns OAuth, PKCE, sessions, and tokens. app.Brand(...) still applies; the headless view model exposes it. For full control over the redirect use app.Headless(headless => headless.BuildUiUrl = …). There is no separate dashboard toggle: BuildUiUrl present means headless. Build your own login UI · Hosted vs headless
AddSqlOS does not automatically bind an SqlOS configuration section. Read values from builder.Configuration, your secret store, or environment variables and assign them in the options callback as shown above. (options.UseSingleApplication(builder.Configuration) binds just the application description from SqlOS:Application.)
Your front end (a browser SPA, a native app, or an agent) uses its standard OIDC client library to sign in as the derived client, with either hosted AuthPage or headless authentication UI, and calls /api with the resulting bearer token. AddSqlOS protects the endpoints you map under the declared surfaces; there is no middleware to place. See the complete Notes sample.
UseSingleApplication creates one first-party PKCE client, a callback at {Origin}/auth/callback, a default client allowlist (openid, profile, email, offline_access), and matching AuthPage branding. With OpenID Provider mode enabled (the default), authorization-server metadata advertises openid, profile, and email; offline_access stays on the client only for gateway compatibility and is not advertised, because SqlOS issues refresh tokens to code-flow clients without gating them on that scope. DCR stays off; CIMD and resource indicators turn on only when you declare Mcp.
Switch the EF callback to UseNpgsql(connectionString) to run the same host on PostgreSQL. See Choose SQL Server or PostgreSQL.
Install the package and declare one application with UseSingleApplication.
Run the Todo sample with SQL Server or PostgreSQL, hosted login, and FGA already wired.
Use ASP.NET Core OAuth, PKCE, a secure cookie, and revoking logout.
Compare the runnable .NET, browser, mobile, and CLI examples.
Adding SqlOS to your application is the canonical integration path; running the sample is the fastest evaluation. Do not begin with SAML, FGA modeling, CIMD, or DCR unless one of those is already a product requirement.
When other applications should sign in with your accounts — another browser application, a CLI alongside it, or a partner app using "Sign in with Acme" — the same host becomes an identity provider. Replace UseSingleApplication with ConfigureApplication to retain the host description, then declare each client explicitly with options.AuthServer.SeedClient(...) (or create them from the dashboard or admin API; all three share one validation and audit path). Everything from the standard flow still applies; you additionally get per-client consent, audiences, portable-client registration, and machine clients.
Runnable examples use this API: the retail stack serves Next.js, Angular, and Expo; the Todo stack serves Razor Pages and the CLI. A separate frontend and API can still be one client application; API/MCP resources do not themselves require additional browser-client registrations.
→ Multiple applications · Sign in with X · Clients
Complete Run the Todo sample or Add SqlOS to an app.
Let the framework own PKCE, correlation state, the callback, and your application cookie with Sign in an ASP.NET Core app.
Declare app.Api = "/api", call RequireAuthorization() on the groups you lock, and read the validated token with Protect an API.
When role checks stop being enough, declare app.Authorization(...) and filter rows in SQL with EF Core authorization.
Continue into invitations, social login, SAML SSO, MFA, audit logs, an MCP server, or a custom login UI.
Move to explicit clients when a second application must sign in with your accounts: Multiple applications.
When the host starts, SqlOS initializes and upgrades its own tables, automatically creates and protects a signing key when none exists, and applies settings and startup seeds. Your EF migrations continue to own your application tables. AddSqlOS also maps the OAuth, hosted login, and admin API routes and registers the dashboard middleware at startup.
Default paths:
| Path | Purpose |
|---|---|
/sqlos | Embedded dashboard |
/sqlos/auth | OAuth server and hosted login |
/sqlos/admin/auth | Auth administration |
/sqlos/admin/fga | Authorization administration |
Create email-bound, one-time organization invitations.
Configure Google, Microsoft, GitHub, Apple, or custom OIDC.
Connect an organization to a SAML identity provider.
Capture application and SqlOS governance events.
For the complete task directory, start at the documentation home. Use Example applications when you want a complete source path instead of an isolated integration step, and use the reference section after you know which service or endpoint you need.