You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 2206138
Browse filesBrowse the repository at this point in the historyBrowse files
fix(credentials): enforce the saved-credential contract on every credential block, reopen key-based reconnects on their mode, and tighten fixtures and skills
- check-block-registry runs the saved-credential contract for every block with a
saved-credential picker, not only successors; the per-block contract moves to
saved-credential-contract.ts with tests. The host probe gains a path-shaped id and a
per-param shape so mixed-validation builders (Jama, Higgsfield) are probed, not guessed.
- Blocks the widened check caught: Coda, Harmonic, and Oracle Database tools declare
credentialKind 'service-account'; NetSuite pins instanceUrl in authoritativeParams;
Vanta's assetExternalAccountId is a filter, not a host.
- prepareWorkloadIdentity covers every keyless provider (AWS, Databricks added) and
reuses audiences.ts for the provider-id mapping; the AWS and Databricks dialogs reopen
a reconnect on the stored mode.
- Snowflake keyless verification maps an egress refusal to host_not_allowed.
- Neutral token fixtures in new credential tests; subject uniqueness TSDoc; skills
describe native token blocks, the picker shape, keyless setup, and the successor naming
exception.
A service-account-only picker (a saved token or key credential) instead sets
141
+
`credentialKind: 'service-account'` and `mode: 'basic'` (no scopes), and pairs with an advanced
142
+
twin; `isSavedCredentialPicker` matches only this shape:
143
+
```typescript
144
+
{
145
+
id: 'credential',
146
+
title: '{Service} Account',
147
+
type: 'oauth-input',
148
+
serviceId: '{service}',
149
+
credentialKind: 'service-account',
150
+
canonicalParamId: 'oauthCredential',
151
+
mode: 'basic',
152
+
placeholder: 'Select {Service} credential',
153
+
required: true,
154
+
},
155
+
{
156
+
id: 'manualCredential',
157
+
title: '{Service} Account',
158
+
type: 'short-input',
159
+
canonicalParamId: 'oauthCredential',
160
+
mode: 'advanced',
161
+
placeholder: 'Enter credential ID',
162
+
required: true,
163
+
}
164
+
```
165
+
139
166
**Scopes:** Always use `getScopesForService(serviceId)` from `@/lib/oauth/utils` for `requiredScopes`. Never hardcode scope arrays — the single source of truth is `OAUTH_PROVIDERS` in `lib/oauth/oauth.ts`.
140
167
141
168
**Scope descriptions:** When adding a new OAuth provider, also add human-readable descriptions for all scopes in `SCOPE_DESCRIPTIONS` within `lib/oauth/utils.ts`.
@@ -695,7 +722,8 @@ outputs: {
695
722
When creating V2 blocks (alongside legacy V1):
696
723
697
724
```typescript
698
-
// V1 Block - mark as legacy
725
+
// V1 Block - mark as legacy. A credential-only successor is the exception: the
726
+
// successor keeps the legacy block's name, so neither block is renamed.
Copy file name to clipboardExpand all lines: .agents/skills/add-integration/SKILL.md
+22-7Lines changed: 22 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,6 +43,12 @@ supported paths and choose the simplest supported setup for the intended user:
43
43
| Customer-owned client credentials | Saved `service_account` credential with a client ID and secret | Internal-app eligibility, grant activation, scope syntax, token lifetime and revocation behavior |
44
44
| API token or personal access token | Saved token service account when reusable connections are useful | Token permissions, identity verification, expiry and rotation |
| Cloud workload identity (AWS role, Databricks/Snowflake/Entra/GCP federation) | Keyless saved credential: Sim signs a short-lived OIDC token the customer's cloud trusts. Add the provider to every table in `lib/credentials/workload-identity/audiences.ts` (`WORKLOAD_IDENTITY_PROVIDERS`, its service-account provider ID map, `WORKLOAD_IDENTITY_KEYLESS_CONFIGS`, `WORKLOAD_IDENTITY_AUDIENCES`) and to `MIXED_MODE_PROVIDERS` in `lib/credentials/application/prepare-workload-identity.ts`| Issuer and audience the provider accepts, how the trust pins the subject, token lifetime |
47
+
48
+
API, CLI, and MCP callers set up keyless in two steps: `POST /api/v2/credentials/workload-identity/subjects`
49
+
(or `sim credentials keyless-subject <providerId> --output json`) returns the subject to trust and a
50
+
`keylessConfig`; they add its `requiredConfigFields` and create the credential with it. The provider
51
+
catalog advertises `keyless` only when the deployment can sign tokens.
46
52
47
53
Do not present customer-owned credentials as a way around a provider's approval requirements
48
54
for a shared public integration. Explain the supported account/app type in the setup docs. Keep
@@ -86,15 +92,23 @@ service id:
86
92
answers), and `errorBodyEchoesToken` when an error body echoes the token.
87
93
3.`apps/sim/lib/oauth/oauth.ts` and `types.ts`: the service entry (`authType: 'service_account'`,
'providerWorkspaceId' })` in `apps/sim/tools/shared/saved-credentials.ts`, listed in
100
+
`SAVED_CREDENTIAL_OAUTH`, is for existing tools that already take the token inline (successors).
101
+
Either way, the executor overwrites mapped and pinned params after authorizing the credential,
102
+
and `check-block-registry` probes the real URL builders of every block with a saved-credential
103
+
picker and fails on a host-steering param left unmapped or unpinned.
94
104
5. A credential-only block (including a successor) uses `authMode: AuthMode.OAuth`, so the
95
105
generated catalog maps the service; a token-only block that keeps `AuthMode.ApiKey`, as Coda
96
106
does, registers in `tokenCredentialIntegrationTypes` instead (see below). The credential picker
97
-
sits directly under the operation dropdown (`add-block` → OAuth/Credentials). An existing block that already takes the secret inline is never edited in
107
+
sits directly under the operation dropdown (`add-block` → OAuth/Credentials). A new block
108
+
writes the picker inline, as Higgsfield does: `{ id: 'credential', type: 'oauth-input', serviceId,
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/aws-account-modal.tsx
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/integrations/components/connect-service-account-modal/databricks-account-modal.tsx
+11-3Lines changed: 11 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -93,9 +93,17 @@ function DatabricksAccountForm({
0 commit comments