Client ID Metadata Documents
Use CIMD when a public client should identify itself with a stable HTTPS metadata document.
CIMD is the portable-client path in SqlOS.
Instead of creating a local client first, the client uses a stable HTTPS client_id. SqlOS fetches that URL, validates the JSON, and caches the metadata in the existing client store.
Use CIMD when:
scopeDo not start here if you are just wiring your own first-party web app. Seed a client first and keep the first version simple.
CIMD is disabled by default. With UseSingleApplication or ConfigureApplication, app.Mcp = "/mcp" turns it on together with resource indicators, because portable clients that speak MCP need both. On a host that does not declare Mcp, set the flags:
builder.AddSqlOS<AppDbContext>(
db => db.UseSqlServer(connectionString),
options =>
{
options.ConfigureApplication("Acme", app =>
{
app.Origin = "https://auth.example.com";
});
options.AuthServer.ClientRegistration.Cimd.Enabled = true;
options.AuthServer.ClientRegistration.Cimd.DefaultCacheTtl = TimeSpan.FromHours(12);
options.AuthServer.ClientRegistration.Cimd.TrustedHosts.Add("clients.example.com");
});When TrustedHosts is empty, any syntactically valid HTTPS client-ID URL with a non-root path is eligible for an outbound metadata request. SqlOS resolves and connects directly to public addresses only, rejects mixed public/private DNS answers, and does not follow redirects. In production, disable CIMD when portable clients are unnecessary; use TrustedHosts as an additional allowlist when your client population is closed.
Disable it explicitly when the host accepts only seeded or dashboard-managed clients:
options.AuthServer.ClientRegistration.Cimd.Enabled = false;SqlOS expects:
client_id with a pathclient_id exactly matches the URL usedclient_nameredirect_uristoken_endpoint_auth_method=none in v1scope, stored as the client's registered allow-listSqlOS also:
http://127.0.0.1/..., http://[::1]/...) port-insensitively per RFC 8252 §7.3, so native clients like Codex can register a portless loopback redirect and bind an ephemeral port at login; scheme, address, path, and query must still match exactly, and localhost or HTTPS redirects always require an exact matchscope as registered metadata (there is no separate CIMD ceiling; later grants still intersect requested scopes with that stored allow-list)scope as a security-sensitive metadata change, the same as a redirect, grant-type, response-type, or token-endpoint auth-method change: active sessions are revoked and SqlOS records client.cimd.metadata-changedopenid in a CIMD document is an ordinary allow-listed string, and the document's scope behaves like any other allowlist: with OpenID Provider mode enabled (the default), declaring openid there makes the client OIDC-capable, and a grant that includes openid receives an id_token.
TrustedHosts is checked before the network request. Use TrustPolicy when you also need to inspect parsed metadata after retrieval:
builder.AddSqlOS<AppDbContext>(options =>
{
options.AuthServer.ClientRegistration.Cimd.TrustPolicy = async (context, cancellationToken) =>
{
if (!context.ClientIdUri.Host.EndsWith(".example.com", StringComparison.OrdinalIgnoreCase))
{
return SqlOSClientRegistrationPolicyDecision.Deny("Only example.com metadata hosts are allowed.");
}
return SqlOSClientRegistrationPolicyDecision.Allow();
};
});That is the right place for:
SqlOS enforces public-address-only connections before sending the HTTP request. TrustedHosts and TrustPolicy add application-specific acceptance rules; they do not replace the built-in DNS/IP and redirect protections.
CIMD clients appear in the normal client list with source and cache details.
Operators can: