OAuth Client
A reusable OAuth2 client profile for connector elements: define the provider's client id, secret reference, endpoints, scopes, and token auth method once, then let many connector elements reference it while the platform keeps one stable provider callback URI.
Working with it
Selecting a OAuth Client reveals its settings in the properties panel; it has no dedicated full-screen workbench.
How it appears
The same element type rendered as a definition, a circle instance, and a live workspace card.
When to use / not
When to use
- A circle wants to connect a provider that is not a dedicated Triform element yet, such as Xero, through a generic io/http element.
- A partner or operator wants to own the OAuth app and secret while customer circles only hold their per-company grants.
- Multiple connector elements should share the same OAuth app metadata without copying client ids, endpoints, and scope lists.
When not to use
- You only need a static API key or bearer token; use variable or an HTTP auth credential instead.
- The provider does not support OAuth2 authorization-code grants.
- The connector needs provider-specific non-OAuth behavior; model that in the connector element's own ops.yaml.
Topology
Attaches to another element as a modifier, shaping that element's behaviour rather than running on its own.
Properties
provider_keystringrequired- Stable credential key used in stored connector grants (for example fortnox, xero, stripe-custom). It does not need to match an element type.
authorize_urlstringrequired- OAuth2 authorization endpoint
token_urlstringrequired- OAuth2 token endpoint
client_idstringrequired- OAuth application client id
client_secret_refstringrequired- Variable/secret reference for the OAuth client secret. If this profile is owned by a partner or platform circle, the secret is resolved in the profile's home circle.
token_auth_methodstring- How the client authenticates to the token endpoint. Use basic for client_secret_basic providers; use client_secret_post for providers that require credentials in the form body.
redirect_uristring- Optional override for the OAuth redirect URI. Omit to use the platform stable connector callback: /api/oauth/connect/callback.
scopesarray- OAuth scopes requested during consent
authorize_paramsobject- Provider-specific static authorization query parameters. Defaults such as response_type=code and access_type=offline are added automatically unless overridden here.
docs_urlstring- Provider OAuth setup documentation
Capabilities
Inherited from modifiers
- Evaluate
- Observe
Operations
- attachPOST
- deleteDELETE
- detachPOST
- disablePOST
- enablePOST
- evaluatePOST
- getGET
- get_attached_modifiersGET
- intentionGET
- list_attachmentsGET
- readmeGET
- readme_updatePOST
- schemaGET
- updatePATCH
Errors / when it fails
- provider_key must be 2-64 characters long
- Fails unless:
len(provider_key) >= 2 && len(provider_key) <= 64
Validation rules
- No redirect_uri override set; the platform stable connector callback /api/oauth/connect/callback will be used
OAuth Client (oauth-client)
Category: modifiers | Form: | Symbol: Oq
Reusable OAuth2 client profile for connector elements
Stores OAuth2 client metadata (provider key, authorize/token endpoints, client id, secret reference, scopes, token auth method, and optional provider-specific authorize parameters). Like api-token and variable it is a settings modifier — it does not cascade or intercept requests; connector elements such as fortnox or http reference it via spec.oauth.profile_ref so the platform uses one stable callback URI while routing each grant by signed state. The client secret is never stored inline: client_secret_ref points at a variable/secret resolved in the profile’s home circle, which is what makes partner-managed profiles safe to reference cross-circle.
Guide
Reusable OAuth2 client profile for connector elements
What It Does
OAuth Client stores the OAuth2 application registration — the half of an OAuth setup that belongs to you rather than to any one user: the provider’s authorize and token endpoints, your client id, a reference to the client secret, the scopes you request, how the token endpoint expects to be authenticated, and any provider-specific parameters the authorize URL needs.
It exists so that registration is declared once and reused. Several connector elements can share a single OAuth Client rather than each carrying its own copy of the same endpoints and credentials — and when a provider rotates a secret or changes an endpoint, there is one element to update instead of one per connection.
Like api-token and variable, this is a config-bearing modifier: it holds no data of its own and exposes no operations. It is attached to the connector elements that need it.
Element Definition
| Property | Value |
|---|---|
| Type | oauth-client |
| Category | modifiers |
| Form | modifier |
| Symbol | Oq |
| Icon | key / #0EA5E9 |
Configuration
| Field | Purpose |
|---|---|
provider_key | Short identifier for the provider this profile targets |
authorize_url | Provider endpoint the user is redirected to for consent |
token_url | Provider endpoint that exchanges a code for tokens and refreshes them |
client_id | Your application’s public client identifier |
client_secret_ref | Reference to the stored secret — the secret itself is never inlined here |
token_auth_method | How the token endpoint expects the client to authenticate (varies by provider) |
redirect_uri | Callback URI registered with the provider |
scopes | Permissions requested at authorize time |
authorize_params | Extra provider-specific query parameters some providers require |
docs_url | Link to the provider’s OAuth documentation, for whoever configures this next |
client_secret_ref is a reference rather than a value on purpose: the profile can be read, exported, and shared between connectors without carrying the secret with it.
Operations
None. This element is configuration attached to other elements; the connectors it is attached to perform the OAuth flow using the profile it carries.
Capabilities
- oauth-client-profile: Holds reusable OAuth2 app metadata that connector elements reference via spec.oauth.profile_ref
- stable-callback: Works with the platform stable callback /api/oauth/connect/callback; target routing is encoded in signed state
- partner-managed-secret: When referenced cross-circle, client_secret_ref is resolved in the profile’s home circle
- custom-provider: Provider key is data, not an element type, so users can define OAuth profiles for Xero or other APIs without physics changes
Properties
| Property | Type | Default | Description |
|---|---|---|---|
provider_key | string | — | Stable credential key used in stored connector grants (for example fortnox, xero, stripe-custom). It does not need to match an element type. |
authorize_url | string | — | OAuth2 authorization endpoint |
token_url | string | — | OAuth2 token endpoint |
client_id | string | — | OAuth application client id |
client_secret_ref | string | — | Variable/secret reference for the OAuth client secret. If this profile is owned by a partner or platform circle, the secret is resolved in the profile’s home circle. |
token_auth_method | string | "basic" | How the client authenticates to the token endpoint. Use basic for client_secret_basic providers; use client_secret_post for providers that require credentials in the form body. |
redirect_uri | string | — | Optional override for the OAuth redirect URI. Omit to use the platform stable connector callback: /api/oauth/connect/callback. |
scopes | array | [] | OAuth scopes requested during consent |
authorize_params | object | — | Provider-specific static authorization query parameters. Defaults such as response_type=code and access_type=offline are added automatically unless overridden here. |
docs_url | string | — | Provider OAuth setup documentation |
Operations
attach
Post /ops/attach | Auth: Read
Attach this modifier to a target element
Attaches this modifier to a target element. The target_id must be a UUID of an existing element that supports this modifier type (check applies_to in definition.yaml). Priority controls evaluation order when multiple modifiers of the same type are attached — lower priority runs first. The attachment is stored in element_modifiers table. Cascade resolution runs at bond-time to merge this modifier into the target’s resolved config. Common mistake: attaching to an incompatible element type — check topology rules first.
delete
Delete /ops/delete | Auth: Admin
Delete element (soft delete)
Soft delete — sets state to ‘deleted’ but retains the record. Cannot delete elements that have children (has_no_bond precondition) or active runs. Requires admin auth and confirmation.
detach
Post /ops/detach | Auth: Read
Detach this modifier from a target element
Removes this modifier from a target element. Requires the target_id. Pervasive modifiers (audit, policy) can only be detached at the level they were originally attached — inherited pervasive modifiers cannot be detached by child elements. After detach, cascade resolution re-runs to remove this modifier’s effect from the resolved config.
disable
Post /ops/disable | Auth: Admin
Disable element (hides and prevents use)
Idempotent — safe to call on already-disabled elements. Optionally pass a reason string. Disabled elements cannot be invoked or executed. Inverse of enable.
enable
Post /ops/enable | Auth: Admin
Enable element (makes usable and visible)
Idempotent — safe to call on already-enabled elements. Transitions element to ready/enabled state. Cannot enable deleted elements. Inverse of disable.
evaluate
Post /ops/evaluate | Auth: Read
Evaluate modifier against current context
Evaluates this modifier against a context and optional target_id. Returns applies (bool), result (modifier-specific), and message. For modifiers without custom evaluation logic, returns a default pass result. Auth-policy returns allowed/denied. This is the explicit evaluation endpoint — during normal request flow, modifiers are evaluated automatically by the cascade resolver as middleware.
get
Get /ops/get | Auth: Read
Get element details
Element is already resolved by the routing layer — this returns the cached element, not a fresh DB query. Use the path /api/{circle}/{slug} to address elements.
get_attached_modifiers
Get /ops/attached/{target_id} | Auth: Read
Get all modifiers attached to a target element
Lists all modifiers attached to a specific target element, including modifier_id, type, subcategory, and priority. Useful for debugging cascade resolution or understanding which policies apply to an element before invoking it.
intention
Get /ops/intention | Auth: Read
Get element intention with full inheritance chain
Returns three levels: direct (this element’s intention), inherited (from category and root), and resolved (final merged intention). Useful for understanding an element’s purpose in context of its hierarchy.
list_attachments
Get /ops/targets | Auth: Read
List all elements this modifier is attached to
Returns all target elements where this modifier is currently applied. Shows target_id, target_type, priority, and cascade_policy.
readme
Get /ops/readme | Auth: Read
Get element README.md content
Reads README.md from the element’s git repository. Returns empty content (not an error) if no README exists. Always returns markdown format.
readme_update
Post /ops/readme_update | Auth: Write
Update element README.md content
Creates or overwrites README.md in the element’s git repo. Commits to the draft branch. Content must be provided as a markdown string.
schema
Get /ops/schema | Auth: Read
Get element input/output schema (MCP tools/list compatible)
Returns type-level port schemas from the TypeRegistry — not instance-specific overrides. Includes direction (input/output), required flag, and JSON schema per port. Useful for understanding what data an element accepts and produces.
update
Patch /ops/update | Auth: Write
Update element
Partial update — send only the fields you want to change.
spec,name, andintentionare all independently optional.specMUST be a JSON object when present; deep-merged into the existing spec by default. Empty{"spec":{}}preserves existing spec content but still records a new version (no-op for content, not for version state). To clear/replace the entire spec wholesale send{"spec":{...},"deep":false}. List-typed spec fields use replace semantics (the patch list replaces the existing list, no array merging). Coordinates Git + DB writes. Slug cannot be changed after creation.
Lifecycle / runtime
Inherited from modifiers
Execution model: async
Observability
Inherited from modifiers
Metrics
- evaluation_count
- evaluation_duration_ms
Pricing / cost
Platform default
Operation costs
- create: free
- update: free
- delete: free
- get: free
- list: free
- invoke: 10000 micro-AU
- tool_use: free