OAuth applications
An OAuth application lets a third-party client act on OSO data on a user's behalf, without anyone pasting a long-lived key. The user signs in to OSO, picks which of their organizations the client may reach, and approves a named set of permissions. This page covers publishing an application and the rules that govern it.
You do not need an application of your own to connect a client that already has one — see MCP Server for connecting an agent. Publish one when you are building the integration and want it to carry your organization's identity and credentials.
Publish an application
You must be an owner or admin of the organization.
The form requires at least one callback URL and will not save without one. If you reach step 4 without it, you cannot finish — and the client secret is shown at step 5, once and only once.
- Open your organization's Settings → OAuth Apps.
- Create an application and give it a name your users will recognize on the consent screen. An admin of your organization vouches for this name by publishing it.
- Choose the scopes it needs. Ask for the narrowest set that works — see Scopes.
- Under Authorization callback URLs, add the URL the client will be
redirected back to. At least one is required. All URLs must use HTTPS,
except on localhost (
localhost,127.0.0.1and[::1]may usehttp). URLs are stored normalized, so what you see after saving may differ slightly from what you typed. - Save. OSO shows the
client_secretonce. Nobody — including OSO — can retrieve it again; losing it means rotating the secret, which breaks any client already using the old one.
The client then uses the client_id and client_secret to start the
authorization flow.
Clients without credentials
A client can also identify itself with a Client ID Metadata Document
instead of registered credentials: its client_id is an HTTPS URL that OSO
fetches to learn who the client is. OSO admits this only from an allowlist of
origins, and such a client needs no callback URL configured here.
This does not bypass your organization's control. An owner or admin still
authorizes the client per organization, and the grant appears in Settings →
OAuth Apps where it can be revoked like any other.
OSO registers clients this way, not through Dynamic Client Registration.
There is no /register endpoint and the discovery document deliberately
advertises none, so do not go looking for one.
What the consent screen asks
The consent screen names the client, lists the permissions it is asking for in plain language, and lets the user pick which organizations to authorize.
The identity line at the top depends on how the client identifies itself:
- A published application is shown by the name an
owner/adminof the publishing organization chose, along with that organization. OSO does not review these names — the screen tells you which OSO organization stands behind the application, not that anyone vetted what it calls itself. - A credential-less client is shown by the origin of its
client_idURL, with any name it claims for itself underneath as secondary. The origin is the part bound by DNS and TLS, so it is the part worth reading; a display name is just a string the client asserts about itself. (When a client claims no name, the secondary line is omitted rather than repeating the origin.)
In both cases the durable identity is the organization or the origin — never the display name.
Organizations are ticked individually, and only those where the user is an
owner or admin are selectable.
If you are not an owner or admin
A user who is not an owner or admin of any organization has no Approve
button and cannot connect at all. There is deliberately no request-and-approve
workflow, and no control that lets an administrator authorize a client on
someone else's behalf — an administrator authorizes an organization by
completing the flow themselves.
So ask an administrator either to set the client up on their side, or to make
you an admin of the organization you need.
One grant, several organizations
The token a client receives belongs to the user, not to a single organization. It carries the scopes they approved and nothing else — in particular it does not record the organizations they ticked.
Reach is recomputed on every request instead, from three things at once: the
scopes in the token, the user's current role in that organization, and that
organization's standing authorization of the application. So the token reaches
every organization that has authorized this application and where the user is
still a member — which can be wider than the set they ticked, if another
owner/admin had already authorized the same application for an organization
they belong to.
Consequences worth knowing:
- Revoking one organization's authorization stops the client working for that organization only. Other organizations are unaffected.
- When a user leaves an organization, the client stops working for it immediately — no revocation needed, because membership is re-checked per request.
Revoke from Settings → OAuth Apps in the organization whose access you want
to withdraw. Revoking, like authorizing, requires owner or admin there.
Scopes
Scopes are resource:level strings. write implies read on the same
resource, so asking for datasets:write alone also grants datasets:read.
Resources are independent of each other: holding one resource's scope never
grants anything on another.
| Resource | Scopes | What it covers |
|---|---|---|
organization | organization:read | Your organization's profile and member list. |
runs | runs:read | Pipeline runs, the environments they execute in, and which secrets exist — never a secret's value. |
datasets | datasets:read, datasets:write | Data sources and the tables they materialize. |
agents | agents:read, agents:write | Agent sessions, tasks and their scheduled runs. |
models | models:read, models:write | Notebooks, semantic models and the metrics defined on them. |
connections | connections:read, connections:write | Links to external systems this organization has connected. |
organization and runs are read-only — there is no organization:write or
runs:write. A caller may observe execution and see which secrets exist, but
secret values are not on the schema at all, and creating a run goes through the
scope owning the thing being run.
Troubleshooting
| Symptom | Cause |
|---|---|
| A call fails saying you lack a permission | The token does not carry that scope, the user's role in the organization does not allow it, or the organization's authorization was revoked. All three are checked on every call. |
| The client stopped working for one organization | That organization's authorization was revoked, or the user is no longer a member of it. Other organizations keep working. |
| Authorization fails at the redirect | The callback URL registered on the application does not match the one the client actually used. |
| The client asks the user to sign in again | The access token expired. OSO normally answers an expired token with an invalid_token challenge pointing the client at the metadata it needs to re-authorize. On a call slower than a few seconds the expiry surfaces as an error instead. |
Which server is which
OSO's authorization server for this flow is api.artio.so. Its discovery
document lives at https://api.artio.so/.well-known/oauth-authorization-server
and its endpoints sit under /v1/oauth/.