Summary#
Some things belong to the whole app, not to any one entity or function: the API keys it needs, the OAuth providers it signs users in with, the model it embeds text with, the sensitivity policy over its data. Those are declared once, as typed properties on the app config object, so there is a single place to look and the compiler checks each one.
They fall into two groups: what the app depends on (secrets, OAuth clients, an embedding provider) and policies over the app (classifications, audit access, an MCP surface).
Description#
What the app depends on#
- declaring secrets (app.Secrets) —
app.Secretsdeclares the named secrets the app uses (API keys, tokens, client secrets). Each isnew Secret("Name"); a value is never inlined in source. Mark one{ UserScoped = true }for a per-user secret. - OAuth clients (app.OAuthClients) —
app.OAuthClientsdeclares the third-party OAuth providers, both for signing users in and for calling an external API on a user's behalf. - embedding provider (app.Embedding) —
app.Embeddingnames the embedding model that turns text into vectors, which is what powers semantic search over[Searchable]fields. - per-environment config (app.Config) —
app.Configdeclares the app's per-environment settings (new Setting("Name")), read anywhere asConfig.Name; each environment supplies its values from a checked-in.env.<mode>file. Non-secret configuration — the counterpart toapp.Secrets. - your own file store (app.BlobStore) —
app.BlobStorenames a class of yours (implementingIBlobStore) that keeps the app's file content — a bucket, a table — instead of the platform's own store. - exporting your app's logs (app.LogExport) —
app.LogExportnames a class of yours (implementingIBlobStore) that each finished day of the app's own log lines is written to, once — how an app keeps its logs longer than its plan does. - data held somewhere else (app.DataSources) —
app.DataSourcesregisters the places the app's data can live besides its own database — a warehouse, a SaaS table API — each a named instance of a provider class implementingIEntitySource. - settings a package asks its app for (app settings) — a package (or the app) declares a setting as an
[AppSetting("Name")]class; the app setsapp.Name = new … { … }— plug-ins from any package included — and code reads it withApp.Setting<T>(). - warehouse-time budgets (a data-source query is budgeted before it leaves) — a query to one of those sources is metered in provider milliseconds and refused before it leaves when the day's budget is spent
- The Llm kit — call a model, and know what each call cost —
app.Llmdeclares the models an app may call and the policy that picks one per call; it isOsysharp.Llm's setting, so it arrives withuse Osysharp.Llm; - The Snowflake kit — warehouse tables as entities, and exports back — the optional
Osysharp.Warehouses.Snowflakekit: tables in a Snowflake account as entities your app queries with LINQ, each query running there as one statement carrying the reading person's rule — and an export sink for the other direction. Two lines in the manifest turn it on. - The Databricks kit — lakehouse tables as entities, and exports back — the same two shapes for a Databricks lakehouse, through the same generic seam, which is part of the point: the contract is not shaped around one vendor.
- data sent somewhere else, as it changes (app.Exports) —
app.Exportssends an entity's changes to another system as they commit — a warehouse, a lake — through a sink class implementingIExportSink, in commit order, until the sink has confirmed them all.
Policies over the app#
- data classifications (app.Classifications) —
app.Classificationsmaps a data-sensitivity level (aDataClass— PII, Financial, Secret, …) to the[Role]members allowed to read fields marked at that level. You declare the mapping once; fields opt in with a classification attribute. - audit read access (app.Audit) —
app.Auditdeclares who may read the app's audit trail. The platform records entity changes automatically; this gates the reading of that record. - workflow run retention (app.Workflow) —
app.Workflowdeclares how long FINISHED workflow runs are kept. Undeclared, a completed run is kept for ever with everything it owns; a window reaps it, and a run still in progress is never reaped whatever its age. It is also a ceiling on how long audit read access (app.Audit) can keep the workflow transition trail. - MCP tool server (app.McpServer) —
app.McpServerexposes the app to an MCP client (an AI agent) as a set of tools, grouped into catalogs, each with its own visibility.
UI surfaces the app owns#
- UI surfaces (app.Ui) —
app.Uinominates the app's own components for the system surfaces the platform would otherwise draw a bare fallback for:ConnectionSurface(the server dropped — see Connection),NotFoundSurface(404),ForbiddenSurface(403), andErrorSurface(an unexpected load failure).
One object, checked at compile time#
Because each of these is a typed declaration rather than a config file parsed at boot, a missing provider, a
misspelled role, or a secret that no code reads is caught when the app compiles — not in production. The
use declaration is the companion in the manifest: use brings a capability's tables and types into
the app; the config object here tunes how the app uses them.
See also#
- declaring secrets (app.Secrets) · OAuth clients (app.OAuthClients) · embedding provider (app.Embedding) — the app's external dependencies
- data classifications (app.Classifications) · audit read access (app.Audit) · MCP tool server (app.McpServer) — the app-wide policies
- use — declaring a capability the app depends on