AuthServer
Token Validation
Validate access tokens and extract user claims.
Access tokens are RS256 JWTs. Validate on the server for each API call and always require the audience for the API that will process the token.
using SqlOS.AuthServer.Extensions;
app.UseSqlOSAccessTokenValidation(options =>
{
options.ExpectedAudience = "https://api.example.com";
options.ShouldValidate = http => http.Request.Path.StartsWithSegments("/api");
});The middleware rejects requests at startup if ExpectedAudience is empty. On successful authentication it sets HttpContext.User and stores the SqlOSValidatedToken on the current request:
var validated = httpContext.GetSqlOSValidatedToken();
var userId = validated?.UserId;var bearerToken = httpContext.Request.Headers.Authorization.ToString();
if (!bearerToken.StartsWith("Bearer "))
return Results.Unauthorized();
var expectedAudience = "https://api.example.com";
var validated = await authService.ValidateAccessTokenAsync(
bearerToken["Bearer ".Length..].Trim(),
expectedAudience,
ct);
if (validated == null)
return Results.Unauthorized();
// Use the validated claims
var userId = validated.UserId;
var orgId = validated.OrganizationId;The example app uses middleware to extract the subject ID from multiple auth methods:
public static string? GetSubjectId(this HttpContext http, string expectedAudience)
{
// Bearer JWT
var auth = http.Request.Headers.Authorization.ToString();
if (auth.StartsWith("Bearer "))
{
var token = auth["Bearer ".Length..].Trim();
var validated = http.RequestServices
.GetRequiredService<SqlOSAuthService>()
.ValidateAccessTokenAsync(token, expectedAudience, ct).Result;
return validated?.UserId;
}
// API key (service accounts)
if (http.Request.Headers.TryGetValue("X-Api-Key", out var apiKey))
return apiKey.ToString();
// Agent token
if (http.Request.Headers.TryGetValue("X-Agent-Token", out var agentToken))
return agentToken.ToString();
return null;
}ValidateAccessTokenWithoutAudienceForIntrospectionOnlyAsync exists only for diagnostics and token introspection flows that do not authenticate a protected API request. It validates issuer, signature, lifetime, and session state, but it intentionally does not validate aud.
External services can validate SqlOS JWTs without calling the SDK by using the JWKS endpoint:
GET /sqlos/auth/.well-known/jwks.jsonAnd the OAuth metadata endpoint:
GET /sqlos/auth/.well-known/oauth-authorization-server| Claim | Description |
|---|---|
sub | User ID |
sid | Session ID |
client_id | OAuth client |
org_id | Organization (if scoped) |
iss | Issuer URL |
aud | Audience |
exp | Expiration |