Connecting Accounts
How personal OAuth accounts are connected — from Settings or directly from a workflow block — and how to troubleshoot a connect that fails
OAuth-based extensions (GitHub, Google, Microsoft, …) distinguish two things:
- The extension itself — installed and configured by an organization admin under Settings → Platform → Extensions. This stores the org-level OAuth client credentials (Client ID / Client Secret) and creates a connection for what it provides. An extension showing Active here means the org has it configured and enabled — it does not mean your personal account is linked yet.
- Your personal account — the OAuth account you authorize against that extension. A workflow block does not offer a selector to choose between accounts; it automatically uses whichever account the identity running the workflow (you, or the service account it runs as) has connected for that provided item.
API-key connections and regional AI resources
The Connections → Add connection form uses the extension's credential definition, including its key label and configuration fields. Azure AI Foundry asks for its resource API key and Foundry endpoints. Microsoft OAuth products ask for a Client ID and Client Secret. If an extension offers several authentication methods, choose the method in the form. Products with an explicit credential requirement receive only compatible credentials.
For multiple Foundry resources, install the extension once and add named connections such as North Europe, Sweden Central, and West Europe. Give each connection its own resource key and endpoints, and choose its environment scope. Editing a connection shown as covering several products updates that group's configuration together.
In Settings → Platform → Extensions → Models & defaults, choose All environments
to edit the shared default, or an organization environment such as Development or
Production to override it. Personal configures Personal workspaces, whose internal
environment identifier remains main. The selector does not switch your active workspace.
Open a capability's searchable dropdown to load models across every eligible connection:
- All environments includes connections configured for all environments.
- A specific environment includes its own connections plus shared connections, subject to the organization's wildcard connection policy.
- Entries are grouped by vendor and connection. Identical model names on different Azure resources remain separate choices; choosing one pins that connection and model.
- Automatic chooses an eligible vendor/model at execution time. An Automatic override replaces an inherited pin. Use shared default removes the override.
The catalog is organization-wide, so you can configure Development or Production while working in Personal. The dropdown only offers eligible model choices; models explicitly reported as unavailable or unverified are omitted. Workspace permissions and clearance still apply when a workflow runs. Production-only credentials are never borrowed by Development or Staging.
Existing saved connection pins remain pinned, including older organization-wide defaults that named an environment-specific connection. If a connection is removed, disabled, or inaccessible, execution reports an unavailable configuration until you choose a replacement. A concurrent policy update rejects a stale save instead of overwriting another environment's settings. Reload the policy before retrying.
Azure Speech routes through the configured Foundry resource endpoint; no separate Azure
Speech Region field is needed for routing. Set Azure Region on each Foundry connection
so the catalog can filter built-in Speech models by Microsoft's regional support. Azure
region (for example, northeurope) is separate from application environment (Development,
Production, or All environments); it cannot be inferred from a resource's user-chosen name.
The STT catalog includes MAI Transcribe 2, MAI Transcribe 1.5, Azure Speech Fast Transcription, and Azure AI Speech — live transcription with speaker labels, alongside discovered deployments. MAI and Fast Transcription use Microsoft's Speech transcription API, without an OpenAI deployment. MAI accepts WAV, MP3, or FLAC audio. MAI's HTTP transcription operation is not a Speech SDK streaming session.
Built-in service entries use the connection's configured Azure region to filter known unsupported models. Built-in Speech models with an unknown region are also omitted until regional support is confirmed. Set Azure Region to the resource's actual region and reopen the selector to refresh its choices; connection names such as Default or Sweden Central do not establish the region. The selector lists choices without an availability badge. If none are available for a capability in the selected environment, the row explains this instead of showing a dropdown. Install and configure extensions from the Installed tab. Catalog support does not prove that a specific resource can execute a model. Opening the selector does not send billable test audio; Azure validates access when transcription is requested.
Microsoft's region table lists ordinary realtime Speech in North Europe, Sweden Central and West Europe, while its LLM/MAI transcription service table includes North Europe but not the other two. Check MAI model availability for the actual resource. Adding a connection does not provision models or enable them in every region.
If choices cannot load, use Try again and check the selected environment and connection.
Endpoint addresses
Some extensions ask for an address on the connection — the URL of your own Twenty or Home Assistant, for example. The form checks it as you type and again when you save, and says which field to fix:
| The address… | What you see |
|---|---|
is not https:// on port 443, or contains a username, password, ? query or # fragment | Use an https:// address on port 443… — the connection is not saved. Local addresses such as http://homeassistant.local:8123 can't be reached from Scrydon. |
| contains the token or password you entered | Remove the access token or password from this address… — enter it in the credential field instead. |
| is valid, but its host is not on the organization's egress allowlist | The connection is saved. Its sources show The connection's address is valid, but your organization's egress allowlist doesn't include its host, with a link to Settings → Governance → Egress, where an administrator adds the host. |
A data source that needs no credential still gets a connection — it is where the address lives. Its form asks for the name, the environment and the address, and nothing else.
A database source needs a connection per environment. It never reads a connection saved for All environments, so when a connection serves one the form does not offer that choice, and it opens on the environment you came from. Connecting the extension from Add extension asks the same question: when it provides a database source, the connect step asks which environment the connection is for and saves it there; anything else it provides keeps All environments. A connection already saved for All environments that serves a database source shows Needs setup — edit it and choose its environment, such as Development or Production. Until then Analytics lists it under Add data source but it cannot be picked, and says why.
One source, several connections
A data source can run through more than one connection in the same environment — for example the States source of a Home Assistant extension reading both your personal and your company Home Assistant. Each is an instance of the source, with its own schedule, status, history and table.
- Open Settings → Platform → Extensions → Installed, select the extension, and open its Connections tab.
- If a system has no connection yet, add one: name, environment, address and credential in one form.
- Choose the environment at the top of the tab. In the source's row, select Add instance. Only organization administrators see it.
- Enter a Name, such as Company. The Short name is filled in from it and names the
instance's table —
ha_states_companyfor company. You can change it: lowercase letters, digits and single hyphens, up to 24 characters. - Choose the Connection. The list offers only enabled connections of this source that are set up for this environment — or for All environments, except for a database source — each marked Ready, Needs setup or Not usable yet.
- Select Add instance.
The instance is listed in the tab and in Analytics → Data Sources under the source's name and its own — Home Assistant states · Company — with its own status, history and table.
The existing instance keeps its connection. When you add the first instance, the source you already had is fixed to the connection it uses now, so adding connections later never switches it. If that source can use several connections in this environment, or none, the dialog asks you to choose the one it keeps.
Adding or moving a connection never switches a running source. Before a new connection is saved for a source's environment (or for All environments), or a connection is moved to another environment, every source that reads exactly one connection there is fixed to it first. A message names them: Kept on the connection they already use: …. To read one of them through the new connection as well, use Add instance on its row; to switch it over, use Change connection. If that check cannot be completed, the connection is not saved and nothing changes — try again.
| The dialog says… | What to do |
|---|---|
| Another instance of this source already uses this short name | Choose another short name. |
| This short name would not give the instance a table of its own | Choose a shorter one. |
| That connection cannot be used here | Choose an enabled connection of this source that is set up for this environment. |
| No connection of this source is set up for … | Add one in the Connections tab, then come back. |
| The connection check could not be completed | Nothing was changed. Try again. |
Changing or removing an instance. In the instance's row in the Connections tab, the ⋯ menu (organization administrators only) offers:
- Change connection — the instance reads from the connection you choose from its next sync. Its table and history stay as they are. The source's original row has it too: it is how you choose between connections when a source reports More than one connection in this environment can serve ….
- Push endpoint (push sources only) — what to configure the system that sends to this instance with: the path it posts to, which ends in the instance's binding ID; the header that carries its credential or signature, and what goes in it; and the header that names each delivery. Each value has a copy button. The path is shown without a host — deliveries go to your deployment's public push host, which your Scrydon operator can give you.
- Remove instance (added instances only) — the instance stops syncing. Its table and its sync history are kept, and its connection is not changed. An instance added later with the same short name writes into the same table again.
When a source's connection is deleted. A source fixed to a connection never switches to another one on its own, so if that connection is deleted or moved to another environment, the source's row reads Needs setup and says The connection this source is fixed to was deleted or no longer applies to this environment. Adding a new connection, even one with the same name, does not replace it: choose one with Change connection. A source that is not fixed to a connection and has none in the environment says No connection in this environment can serve this source yet. Add one in the Connections tab. A source whose connection has no credential saved, or no account connected, says The connection has no credential saved: edit the connection and enter it, or connect its account.
Analytics → Data Sources has no Remove for an instance: its menu offers Manage this instance in Platform, which opens this tab. A source that still has instances can't be removed there either — remove its instances first.
Sign-in providers are different
The Providers section under Settings → Profile → Security links an authentication provider to your Scrydon identity. It is separate from the extension accounts described on this page and uses the deployment's social-login configuration.
Only providers configured by your Scrydon operator appear there. If the Providers section is absent, the deployment has no social-login provider available for account linking; use the enabled sign-in methods or contact your operator. Installing GitHub, Google, or Microsoft under Settings → Platform → Extensions does not enable the corresponding authentication provider.
Where to connect an account
You can connect a personal account from either place — both end in the same vendor OAuth consent screen:
- Settings → Connected Accounts: pick the provider and click Connect.
- Directly from a block: a block whose Identity field shows it has no account yet for that product shows a single Connect <product> button — no dropdown, no account to pick. Clicking it sends you straight to the provider; there is nothing to confirm first. When you return, the block reads as ready with your new account automatically — there is no separate selection step.
Accounts are connected against the extension's Default connection — the connection the platform creates automatically when an admin installs the extension. If your organization uses additional named connections (for example per environment), use Re-authorize on the specific connection in the admin connections panel instead.
Reading the admin connections panel
Settings → Platform → Extensions → <extension> → Connections lists one row per credential, not one per product. A credential that serves several of an extension's products appears once, and the Applies to column names the products it covers — "Outlook", or "7 products" when the list is long.
That matters most for model providers. Installing Azure AI Foundry, for example, provisions the same API key for each of its products (LLM, Embeddings, Speech-to-Text and the rest); the panel shows that as one Default connection applying to seven products, rather than seven identical rows.
Two consequences worth knowing:
- Adding a connection covers every product of the extension. You enter the credential once instead of repeating the form per product.
- Deleting one removes it from every product it covers. The confirmation names them before you commit.
Vendors whose products each need their own grant — Microsoft, where Outlook and Excel are separate OAuth consents — still show one row per product, because those are genuinely different credentials.
Testing a connection
Test connection on a connection's row (and Save & test in its form) sends one real request to the service the connection reaches, with the key saved in the connection, and reports five checks:
| Check | Passes when |
|---|---|
| Address allowed by your egress policy | Every address the connection stores is admitted by your organization's egress allowlist and the deployment's networks — or, for a service whose host the extension fixes, the request actually left. |
| Host reachable (TLS verified) | The host completed a verified TLS handshake, or answered the request. |
| Key accepted | The service answered the request made with the saved key. A rejected key fails this check. |
| Can list and read | That answer was a successful read. |
| Read-only? | The database says the login holds no privilege that writes; see below. |
Each check says Passed, Failed or Unknown, and says why when it did not pass. Unknown never means passed: it means nothing Scrydon sent could answer that question. Once a check fails, the checks after it are not tried. The checks run in order, so a key is never sent to an address your egress policy refuses, or to a host whose certificate did not verify.
What the one request is depends on what the extension already declares:
- An AI model provider (LLM, embeddings, speech and so on): its own model listing. A listing that contains only the models the extension ships with could have come back without the key, so it leaves the key and read checks Unknown rather than passing them.
- A data source that calls an API (a scheduled or on-demand source): the source's own request, sent once exactly as its next run would send it. No rows are read, stored or written. An on-demand source that needs values a person enters when running it is not sent.
- A database source installed through this connection (pinned to it): a read of the database's list of schemas, through the catalog Scrydon keeps for that source with the connection's login. No rows are read. A read that answers proves the host, the login and the read at once; one that does not leaves them Unknown. A database source that is not pinned to this connection is not read.
- Anything else — a stream or push source, a tool-only extension — is not sent a request yet; its live checks stay Unknown and say so.
Read-only? is answered only by a database source's read: Yes when the database lists every privilege the login holds and none of them writes, No when one does. Anywhere else it answers Unknown — no request the test sends asks the service what else the key may do, and a database cannot always tell (a login whose power comes from a role attribute is invisible to its catalog). Prefer a read-only key, login or service account wherever the service offers one.
Good to know:
- Organization administrators can test any connection; anyone else can test a connection they hold Manage on.
- The request is a real one: it may count against your quota at the service. Scrydon records no usage for it and writes nothing.
- A draft connection sends nothing; turn it on to test it with its key.
One account per product, not per vendor
A connected account belongs to one product, not to the vendor as a whole. An account you connect for Outlook cannot be used by a Teams block, and vice versa — even though both sign you in with the same Microsoft identity. The connect control therefore lists one entry per product ("Microsoft — Outlook", "Microsoft — Teams"), and a block only ever reads the account connected for its own product — it cannot use one connected for a different product of the same vendor.
This is also why each connect asks for a different permission set: the consent screen requests exactly what that product needs. In practice you will usually see the consent screen once per vendor — most identity providers return every permission you have already approved for the same application, so connecting a second product for the same vendor often completes without another prompt.
If a block still shows no connected account even though you know you connected one, it was most likely connected for a different product of the same vendor. Connect one for this product instead — either under Settings → Connected Accounts, or from the block's own Connect button if its Identity field shows it is missing one.
Who owns a connected account
Every connected account has an owner in Scrydon, separate from the person who clicked Connect. The owner decides what happens to the credential when people come and go:
| Owner | What it means | When a member is removed |
|---|---|---|
| A member | Their own account — what you get when you connect one from your own settings. | The credential is removed with them. |
| A service account | A machine identity holds the credential. Typical for a shared automation mailbox such as automation@example.com. | Nothing happens — the service account keeps working. |
| The organization | A shared credential every principal uses, such as an app-only registration or an API key. | Nothing happens. |
The Microsoft sign-in behind an automation mailbox is still a real user account at the vendor; ownership is about who holds it in Scrydon, not about the kind of account at the vendor.
Where you connect from decides the owner. Connecting from your own settings gives you a member-owned account. Connecting from a service account's Credentials panel — Connect account / Connect another account — gives that service account the credential straight away, even though a human signs in at the vendor to authorize it. There is no reassignment step to remember, and no window in which an automation credential belongs to a person.
An organization admin can still move an existing member-owned credential to the service account from the same panel — use it to adopt a mailbox somebody connected personally before. Click Transfer ownership on the row marked Person-owned, or Transfer ownership to this service account under a member's account in the Link credential dialog. Both open the same confirmation, which names the account and its current owner; nothing changes until you confirm.
Transferring is an ownership change only:
- The sign-in stays the same. The grant is still that person's identity at the vendor, with the permissions they consented to, and nobody is asked to consent again.
- The lifecycle changes. The credential no longer disappears when that person leaves the organization or disconnects it themselves, and from then on any organization admin can unlink it.
Only organization admins can transfer ownership. If the transfer is refused, the message says why — for example that you are not an admin, or that the account or service account no longer exists.
Whoever signed in at the vendor is recorded separately as the credential's creator. That record never changes hands, and it is not the owner.
A credential owned by a member is one offboarding away from breaking every workflow that runs through it. If a service account uses a member's account, transfer its ownership before that member leaves.
Service accounts and environments
A service account's credential is linked per connection. If a product has a
Dev and a Prod connection, link the service account on each — they are two
different vendor apps holding two different sign-ins, so a Dev link never carries
over to Prod. When a workflow that runs as a service account is promoted to an
environment where nothing is linked yet, the run stops at that step with
RUN_AS_IDENTITY_MISSING, naming the connection to fix.
Granting missing permissions
An account can be connected and healthy yet still lack a permission a particular block needs — for example an account connected before your organization enabled shared-mailbox actions.
When that happens Scrydon names the missing permissions instead of failing when the workflow runs:
- In the block's Identity field — an amber notice lists the missing permissions with an Update access button.
- Under Settings → Connected Accounts — the account shows a Missing permissions badge and a Grant access button.
Either one sends you back to the provider's consent screen for that product only. When you return, the notice clears itself. Nothing else about the account changes — the same account row is reused, so any workspace sharing and any block already pointing at it keep working.
Grant access and Reconnect fix different things. Grant access means the account works but is missing a permission. Reconnect (shown as "Needs reauth") means the account's token can no longer be refreshed and must be re-authorized from scratch.
A block's Identity field shows your own connected account — there is no dropdown listing other people's accounts, and no "Saved by collaborator" state. A run always acts as whoever executes it (you, or the service account it runs as), never as a collaborator who happened to configure the block.
Making an account available to a workspace
A personal account you own is usable in every workspace you belong to automatically — there is no assignment step, because a block never selects an account for you to opt into sharing.
To make your account usable by other members of a workspace, a workspace owner or administrator shares it explicitly from Settings → Workspaces → Extension credentials, and can revoke that sharing from the same panel later, without disconnecting your provider account. A workflow block itself never triggers this — sharing is always an admin action, not a side effect of configuring a block.
Microsoft Teams authorizes the target required by each action. Chat actions such as Write Chat Message select a Chat and do not require a Team. Channel actions require a Team plus their channel input. If a retained pre-production workflow shows a reselect warning, choose the account again; legacy encoded credential strings are intentionally not inferred.
Troubleshooting a failing connect
The connect dialog stays open and shows the error when the authorization URL cannot be built:
| Error | Meaning | Fix |
|---|---|---|
No Default connection found. Install the extension first. | The extension is not installed (or was removed) for this organization. | An org admin installs/enables it under Settings → Platform → Extensions. |
OAuth client credentials are misconfigured for provider … | The org-level Client ID is malformed — e.g. an email address was pasted into the Client ID field. | An org admin corrects the Client ID / Client Secret on the extension's credential form. |
OAuth client credentials are not configured for provider … | The extension is enabled but no Client ID / Secret were saved. | An org admin completes the credential form. |
AADSTS7000215: Invalid client secret provided | Microsoft rejected the configured OAuth application secret. The secret ID may have been entered instead of the secret value, or the value expired. | Create or retrieve a valid client secret value in Entra, save it on the extension, then reconnect. |
Provider shows a redirect_uri warning | The OAuth app registered at the publisher doesn't list your deployment's callback URL. | Register https://<your-host>/api/auth/extensions/account/callback/<provider> on the publisher's OAuth app. |
… signs in against a host set in your organization's settings, so it needs your organization's own OAuth client | The extension's sign-in host comes from your organization's provider settings (for example an Auth0 domain or an Okta/Keycloak issuer), and the organization has no OAuth client of its own for it. A deployment-wide OAuth client, if the operator configured one, is only ever used for vendors whose sign-in host is fixed; its secret is never sent to a host an organization chooses. | An org admin registers an OAuth application at the identity provider and saves its Client ID and Client Secret on the extension's credential form. |
Unsafe OAuth provider configuration: … (when saving, or when connecting) | The extension's provider settings (for example an Auth0 domain or an Okta/Keycloak issuer) produce a sign-in or token address that is not a public https:// host — a private, loopback, link-local or cloud-metadata address, or a name such as localhost. Scrydon calls these addresses from its own servers with your OAuth client secret, so it only calls public HTTPS hosts — or hosts on a private network your Scrydon operator opened to your organization — and never follows a redirect from them. | Enter the identity provider's public HTTPS host. For an identity provider reachable only on a private network, ask your Scrydon operator to open that network to your organization with the Helm value global.egress.privateNetworks; nothing in Settings opens one. Loopback, link-local and cloud-metadata addresses are refused whatever the operator opens. |
The selected extension account belongs to a different connection for this extension. | The identity running the block only has an account connected for another provided item of the same extension (see One account per product). | Connect an account for this specific provided item — under Settings → Connected Accounts, or from the block's own Connect button if its Identity field shows one is missing. |
Extension execution account is missing required scopes: … | The account is healthy but was never granted a permission this provided item needs. | Use Update access in the block, or Grant access under Settings → Connected Accounts. |
| The Connect action is missing from a connection's row | The platform could not resolve which permissions to request for that provided item — usually a partially installed or removed extension. | An org admin reinstalls / re-enables it under Settings → Platform → Extensions. Scrydon deliberately withholds the control rather than connecting an account that could not work. |
After a successful connect you are redirected back to where you started. Under Settings → Connected Accounts the new account appears in your connected-accounts list; on a block, its Identity field automatically reads as ready with the new account — there is nothing further to select.
Microsoft: "Need admin approval"
Microsoft 365 / Teams connects can be interrupted by an Azure prompt:
Need admin approval — Scrydon needs permission to access resources in your organization that only an admin can grant.
This is an Azure Entra (Azure AD) tenant policy, not a Scrydon error: your organization restricts which apps users may consent to, so the Microsoft scopes Scrydon requests require a one-time approval by a tenant administrator. Until that approval is granted, no account is stored — and a Teams block then reports that the Microsoft account is not connected (previously this surfaced as an opaque InvalidAuthenticationToken / IDX14100 401).
To fix it, a Microsoft tenant admin grants consent for the Scrydon app once — either by completing the admin-consent prompt, or via the Entra admin center (Enterprise applications → Consent and permissions). After that, reconnect your account under Settings → Connected Accounts; for a single-tenant organization the admin should also set the extension's Tenant ID to the tenant GUID rather than common.
Once tenant-wide consent is in place, users connect without any approval screen. If non-admin users still see "Need admin approval" even though the Entra portal shows every permission as granted, you are on a Scrydon version that forced a re-consent prompt on every connect (fixed in July 2026) — upgrade, since Entra requires the signed-in user to personally re-approve admin-restricted scopes on a forced prompt, which a non-admin can never do.
Saving a default model
Selecting an entry in Models & defaults saves it immediately. Shared defaults apply to environments without an override. Existing saved choices without a pinned connection keep their original connection-resolution behavior; selecting a replacement pins its connection.
If saving fails, the pending choice remains visible. Use Retry to save it again or Cancel to restore the saved value.