Repository navigation
feat(credentials): saved credentials and credential-only block versions, with keyless AWS/Databricks OIDC - #9763
waleedlatif1 wants to merge 22 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
17321d8 to
ce54794
Compare
f8228bf to
4756748
Compare
There was a problem hiding this comment.
All reported issues were addressed across 2163 files
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Turn on auto-fix | Re-trigger cubic
[High impact] This update appears safe to merge; no new actionable issues were found. SummaryThe PR adds saved credentials, credential-only block versions, and keyless AWS and Databricks connections.
Reviews (4) · Last reviewed commit: "fix(credentials): never cache the issuer..." · Reviewed by Greptile |
…OIDC Adds an optional saved credential to every AWS block and the Databricks block, alongside the existing inline key fields, plus Sim's own workload-identity (OIDC) issuer so a credential can assume a customer's AWS role or federate into a Databricks service principal without any stored secret. Existing workflows are unchanged: the inline fields stay, show, and validate exactly as before until someone selects a saved credential. - Issuer at /oidc/workload (discovery + JWKS), signing key from WORKLOAD_IDENTITY_SIGNING_KEY; 404 and keyless option off when unset - Credential-scoped subjects, HMAC-bound to the preparing user and workspace, so a member cannot reuse another credential's subject - aws-service-account: access keys, keys + AssumeRole (external ID), or keyless AssumeRoleWithWebIdentity; resolved server-side per call - databricks-service-account: PAT, service principal M2M secret, or keyless RFC 8693 token federation - AWS families accept the executor-authorized credential through trusted operation context; clients add the session token only for that pair - S3 get_object signs x-amz-security-token for temporary credentials; inline signatures are byte-identical to before - Tool credential binding honors optional (required: false) policies
…ntials - Models can no longer inject a credential selector (or the token, session token, or host derived from one) into a hybrid tool call, which would have swapped an agent tool's inline keys for another workspace credential - Databricks connections own the workspace host (authoritative `domain`) - Drop the advanced credential-ID input: with a single picker, "is a credential selected" can no longer disagree with the active canonical mode - OIDC subject proofs are bound to their provider - Databricks token and identity fetches refuse redirects - Correct the AWS module doc on presigned URLs carrying a session token
…ial plumbing - Reconnecting a keyless AWS role or Databricks principal keeps its trusted subject by default instead of issuing a new one that breaks the customer's trust policy - The connect dialogs offer the keyless mode only where the deployment can sign tokens; the prepare endpoint reports availability instead of failing - Register AWS (all 19 block types) and Databricks as stored-credential integrations, so org settings, the v2 credentials API, and Copilot can create and see them - Optional STS region for GovCloud and China access keys - One subject binder and config parser shared by both providers (neutral copy), one modal core for submit/errors/trust display - Generic `authorizedServiceAccountCredential` operation context instead of an AWS-specific field; Databricks resolver checks credential type and honors cancellation - Model-blocked params derive from each tool's authoritative params
…nline keys Existing AWS and Databricks blocks are left exactly as on staging, only marked legacy and hidden from the toolbar; placed instances keep running and show an upgrade badge. Each gets a credential-only successor (s3_v2 ... databricks_v2, textract_v3) built by spreading the legacy block and swapping its secret fields for a required saved-credential picker. - withSavedCredential derives the successor's fields, inputs, and params builder; S3 and Textract split their builders so legacy key checks stay - tools declare credentialSuppliedParams so serializer validation and the canonical-id check stop asking credential-only blocks for inline keys - CloudWatch gets saved-credential log group/stream selectors that sign inside the credential's STS session - docs generator resolves multi-level spreads and same-file param builders - the AWS/Databricks providers are derived from the catalog again, so the hand-maintained token-credential mapping is reverted
…l, not inline keys The generator omits a tool's credential-supplied params on pages for blocks that sign in with a saved credential, as it already omits accessToken. Intros now point at the AWS/Databricks credential guides. Regenerates OpenAPI, CLI API, and CLI docs for the new selector keys.
A webhook trigger can register with a field named like the block's secret (PagerDuty, Fathom, EmailBison, GitLab). withSavedCredential now leaves trigger-mode fields, and their dependencies, exactly as they are.
…locks Wave 0 of moving inline-secret blocks onto saved credentials. - tokenCredentialOAuth(provider, credentialParams) declares which tool params a saved token fills; credentialSuppliedParams is derived from it - the executor fills those params after authorization, overriding any caller value, and fails closed when the credential lacks a field - hosted keys are never injected when a saved credential supplies the key - v2 tool execute no longer demands credential-supplied params when a credentialId is passed (fixes AWS/Databricks direct calls) - withSavedCredential accepts an optional/conditional requirement - check-block-registry verifies every credential-only successor's tools authorize the picker's provider and actually fill what they declare - redact secretAccessKey/awsSecretAccessKey keys in logs - serializer contract test covers every operation of each successor
Reference migration for wave 1. A generic tokenCheckValidator verifies a token with one documented authenticated request (no redirects); Tavily uses GET /usage. Legacy tavily is unchanged apart from its legacy marker.
- agent tool-input no longer synthesizes inline secret fields a block's saved-credential picker supplies; one shared rule (credentialSuppliedParamsFor) now drives tool-input, serializer validation, and the canonical-id check - the picker inherits the replaced secret's condition and requirement, so sts_v2's unsigned calls (web identity, SAML) need no credential - withSavedCredential replaces both halves of a canonical secret pair and refuses options that would silently do nothing - Databricks fills its inline apiKey/host through credentialParams, so its tools are byte-identical to staging apart from the policy line - AWS operation families record their tool ids; a test and an executor guard ensure every AWS-credential tool resolves the credential - the registry contract check fails on unpinned host params, optional credentials over required params, malformed pickers, and kind mismatch - hosted-key admission (v2) and pre-resolution validation honor a selected saved credential; credential errors name fields in plain words
…en blocks Each block keeps its legacy definition (only hideFromToolbar + sunset) and gains a credential-only <type>_v2. Every service gets a token-paste provider with a one-request validator against a documented, read-only, credit-free endpoint, and its tools fill the inline key from the saved credential via tokenCredentialOAuth. Blocks: affinity, agentmail, agentphone, ahrefs, apify, apollo, brex, brightdata, browser_use, buffer, circleback, clerk, cloudflare, crunchbase, daytona, elevenlabs, enrich, gamma, hex, huggingface, incidentio, instantly, langsmith, launchdarkly, linq, loops, luma, mailchimp, otter, persona, pinecone, profound, quartr, rb2b, rippling, rocketlane, semrush, sendgrid, similarweb, sixtyfour, smartlead, sportmonks, square, tailscale, trigger_dev, uptimerobot, youcom, youtube. The registry contract check now probes each request tool's real URL builder to find params that steer the host, and requires the saved credential to fill them.
- Pinecone and Semrush leave wave 1: Pinecone's per-call indexHost would let a shared key reach any host, and Semrush has no credit-free check that rejects a wrong key. Both are back to staging exactly. - tokenCheckValidator: forbiddenMeansScoped accepts a valid key that lacks the check endpoint's scope (Apollo, Brex, Bright Data, Apify, Rippling, Persona); acceptsBody proves keys whose rejection arrives in a 200 body (Buffer GraphQL) - the host-steering probe lives in scripts/saved-credential-contract.ts: typed placeholders for required params only, id/host shapes, bare and scheme probes, and a broad destination-name fallback where the URL cannot be built; covered by a fixture test - S3 refuses a bucket or region that would move the signed request's host - spread-inheriting docs keep their base block's outputs (restores the Smartlead, Trigger.dev, and Instantly output tables) - incident.io's credential is optional for alert events, which use their own alert source token - withSavedCredential refuses replaced secrets that show or require differently; copy, intro, and hint fixes from the audit
- host probe also defeats unparsed suffix checks and finds hosts behind optional switches, probing every placeholder shape; broader destination names where a URL cannot be built; the contract check fails when a successor's tool is missing from the executable registry - the optional-credential rule evaluates a conditional picker per operation; incident.io hides its picker on alert events instead - withSavedCredential takes an explicit picker condition and refuses one that depends on a replaced secret at any nesting depth - a scoped 403 counts only when it is the vendor's JSON response, never a firewall or CDN page - S3 names a bad bucket or region in its error - pinecone/semrush catalog dates restored to staging
Their legacy params builders throw without an inline secret, so each is extracted into a module function with a requireKey flag: the legacy block keeps identical validation and messages, the credential-only v2 skips only the key check. discord_v2 hides its picker for webhook posts, which never use the bot token. BlockToolParams is now a shared type for extracted builders (S3, Textract, Discord).
Blocks that already had a v2 get a credential-only v3 that spreads it: cursor, dub, extend, fireflies, intercom, pulse, quiver, reducto. The v2 becomes legacy and every older version's replacedBy points at v3. Extend, Pulse, and Reducto's v2 builders trimmed the key inline, so each is extracted into a builder that takes the key as an argument; the legacy v2 passes the trimmed key exactly as before. Flint gets flint_v2 with a dedicated validator: its API has no read endpoint, so an unknown task id answering 404 proves the key. tokenCheckValidator gains rejectsKey for vendors that answer a bad key with a server error (Fireflies returns 500 auth_failed), so the user is told the key is wrong rather than the vendor down.
- token checks for the 59 new providers live in one module (validators/token-checks.ts) and their tool policies in tools/shared/saved-credentials.ts, so the tool-registry boundary stays within its baselines instead of adding ~60 modules to every graph - the host-steering probe builds URLs through the shared transport (new prepareToolRequestUrl) and also flags a host validated against a vendor allowlist when two accepted values reach different tenants - the AWS routing test reads typed metadata through getToolMetadata - Flint accepts only its documented JSON 'Task not found' 404; Intercom no longer treats a 403 (suspended workspace, plan without API) as valid; Fireflies keeps its error text in logs when a 5xx isn't auth_failed - Cursor help text, placeholder wording, Pulse intro, sorted secret fields
- Refuse a keyless AWS role whose trust policy doesn't pin the credential's subject, so no other workspace can assume it - Treat a malformed workload-identity signing key as not configured - Brex: reject an unknown token's scope-style 403; the token-check factory now runs rejectsKey before accepting a scoped 403 - Flint: probe with a docs-shaped task id and a size-capped body read - Drop the versioned BlockMeta entries that doubled templates; alias bare block types in the app icon map so template icon clusters resolve - Widen the host-probe fallback names and rotate digits in alternates - Copy: picker placeholder casing, Databricks v2 description, Pulse and Tailscale skills, AWS/Persona/Rippling intros, AWS credential docs - Tests: AWS executor signing, AWS/Databricks credential setup, legacy params builders, serializer coverage for blocks without operations
- withSavedCredential reads the replaced fields from SAVED_CREDENTIAL_OAUTH, so blocks and tools share one table instead of two hand-kept copies - Reuse isTriggerModeSubBlock, getDependsOnFields, and a shared isSavedCredentialPicker; build the replacedBy map once in the registry check - newWorkloadIdentitySubject owns the subject format; the AWS trust-pin probe runs alongside verification - The issuer parses a bad signing key once instead of per request - Token checks share the accepted result and the capped JSON reader
- Keyless setup query gets its own key root, so broad credential invalidations can't refetch an open setup and mint a new subject - Named staleTime constant for the setup query - Correct stale comments (relying parties, Databricks param names) - Tighten tests: assert the refusal reason, make the BYOK guard reachable, drop a duplicate and a test that could not fail
- A scoped 403 whose body can't be read is provider_unavailable, never accepted - Provider error snippets read through the bounded reader - Props interfaces for KeylessTrustFields and useWorkloadIdentitySetup; TSDoc on issuer responses
4756748 to
296eb16
Compare
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 2165 files
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Turn on auto-fix | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 2165 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Turn on auto-fix | Re-trigger cubic
Summary
_v2moves to_v3./oidc/workload), so a credential assumes a customer's AWS role (AssumeRoleWithWebIdentity) or federates into a Databricks service principal (RFC 8693) with no stored secret. Key and secret modes remain (AWS access keys, access keys that assume a role; Databricks PAT, service principal secret).tokenCheckValidator), a policy that maps the credential onto the tools' inline params, and a connect form.Existing workflows don't change
hideFromToolbar: trueandsunset: { status: 'legacy', replacedBy }. Placed blocks keep running and editing as before, with an upgrade badge. Nothing is migrated or rewritten.blocks/legacy-builders.test.tspins the same errors and pass-through).serializer/saved-credentials.test.tschecks every legacy block still serializes and requires its inline secret, and every successor serializes per operation with only a credential.get_objectinline signatures are byte-identical to staging (golden test).WORKLOAD_IDENTITY_SIGNING_KEY(or with a malformed one), the issuer returns 404 and the dialogs don't offer keyless.How successors are built
withSavedCredentialswaps the secret fields for a credential picker in the same place (inheriting the secret's condition andrequired), points dependent fields and selectors at the credential, and leaves trigger fields alone. Its replaced fields come from the sameSAVED_CREDENTIAL_OAUTHtable the tools use.oauth.credentialSuppliedParams(andcredentialParamsfor token credentials). The executor overwrites mapped params only after authorizing the credential and fails closed; serializer validation, agent tool-input fields, and v2 execute skip credential-supplied params by the one shared rule.check-block-registryenforces the contract for every successor: provider and kind match the picker, every supplied param is filled, and every param that steers the request host is filled by the credential (probed against each tool's real URL builder), so a shared credential can't be sent to a host the caller picks.Security
subcan't be assumed from another workspace.Deploy notes
WORKLOAD_IDENTITY_SIGNING_KEY(RSA PKCS#8 PEM) per environment, including Trigger workers. Rotate by moving the old key toWORKLOAD_IDENTITY_PREVIOUS_KEY.<NEXT_PUBLIC_APP_URL>/oidc/workload; customer trust policies pin it, so setWORKLOAD_IDENTITY_ISSUERexplicitly before anyone relies on it.Known limits / follow-ups
s3_get_objectsigns its own request, so the executor resolves its session directly; every other AWS tool runs through its operation family.Type of Change
Testing
withSavedCredential, S3 signing goldens. Each new guard was reverted to watch its tests go red.bun run lint, type-check (pre-push),check-block-registry.ts origin/staging, and the docs, catalog, manifest, successor, tool-metadata, deployment-config, React Query, boundary, client-boundary,api-validation:strict, test-pattern, comment, utils and unused-export audits. Fullcheck:auditsand the full suite run in CI.Checklist
test-auditauthoring gate)