Skip to content

fix(release): host_not_allowed for refused hosts, internal-JWT-only secret release, and final release-audit cleanups - #9870

Merged
waleedlatif1 merged 21 commits into
stagingfrom
fix/release-final-leftovers-1110
Nov 11, 2026
Merged

waleedlatif1 merged 21 commits into
stagingfrom
fix/release-final-leftovers-1110

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

The single round-2 cleanup for the staging→main release, agreed across every session working the release audit (it absorbs the separate lists from each audit pass and closed #9867). Low-severity items only; none change product behavior beyond the fixes listed.

Credentials and egress

  • Token-check validators: a refused connection host is reported as a new host_not_allowed 400 ("Sim can't connect to that address…") instead of blaming the token. Under an environment proxy the pre-check now requires every resolved address to pass, so a mixed public/private answer is refused up front; the transport's proxy refusal maps to the same code as a backstop. EgressValidationFailure carries an explicit dns/policy reason; an empty DNS answer is site_not_found; the shared scheme guard strips embedded \t\n\r; Flow and GitLab token checks classify refused hosts the same way. Real transport failures stay 502
  • Saved secrets are released by the token route only to internal-JWT callers (allow-list instead of a session deny-list); the dead browser branch fetchCredentialTokenFromRoute is removed (nothing in the browser executes tools)
  • Databricks: an oversized successful token reply reports 502, not "HTTP 200"
  • Keyless trust-setup refusals no longer name a sibling credential the caller may not see; a broken workload-identity JWKS now logs a warning (still 404)
  • API key creation never echoes an internal failure message to the caller (settings routes and CLI login); the CLI device-flow comment reflects that a refused key creation is terminal

API and docs

  • v2 key auth tells a missing key owner (joined user.id null) apart from an owner whose banned is NULL, so the latter is no longer refused
  • v2 execute option descriptions say a full-access API key or api:write is required (read-only keys are refused); /api/v2/meta example lists search:read; OpenAPI, CLI types, and MCP ops regenerated
  • api-key-read-only flag note: revoke or replace read-only keys before rolling back below this release
  • Redaction keeps Infisical secret names visible (restores fix(release): redact deploy keys, check operation-backed tools in the saved-credential contract, and drop SDK copy #9864's reviewed intent: the bare secretKey pattern masked secret names in run logs); deployKey stays redacted
  • Networking docs: the SSRF guard matches NO_PROXY the way curl does (removes the contradiction with the NO_PROXY section); Helm README and resolveDeployedRunVariables TSDoc corrected

Small fixes and cleanups

  • Firecrawl: a blank maxDiscoveryDepth is treated as unset
  • NO_PROXY: a malformed CIDR entry (10.0.0.0/8/junk) is ignored rather than read as /8
  • Route-cache clear logs a warning when it fails (still non-fatal)
  • GitLab personal-token display uses the integration's own block type, keeping the successor map out of a client-imported module
  • Paused-run point reads are scoped to their workflow; delete-workflow uses the shared requireMutableWorkflow; polling log ids moved to metadata; saved-credential contract builds its payload allowlist once
  • Tests that could not fail were dropped or tightened (delegation fake-DB case, Pi removed-model assertions, Twilio call counts)

Type of Change

  • Bug fix
  • Security fix
  • Documentation

Testing

  • Each behavior fix has a test that fails on the previous code: missing-owner vs NULL-banned key auth, mixed records under a proxy and the transport backstop, oversized Databricks 2xx, internal key-creation message, whitespace scheme, policy refusal and empty DNS answer, Flow and GitLab refused hosts, internal-JWT-only secret release, blank Firecrawl discovery depth, malformed CIDR, and the subject-reuse integration (9, via PostgreSQL)
  • Exact-path unit tests for every touched module; packages/security (211), root scripts (742), sim-cli (528)
  • tsc on apps/sim; check:openapi, cli-api, mcp-operations, v2-route-table, cli-docs, tool-metadata, schema-mock, boundaries, egress-boundary, client-boundary, realtime-prune, tool-registry-boundary, permission-group-enforcement, principal-kind-parity, api-validation:strict, test-patterns, source-conventions; block registry check; biome

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

user.banned is nullable, so a real owner with banned = NULL had every
personal key refused as orphaned. Select the joined user id and test that
instead; the ban and suspension checks are unchanged.
- egress validation names its refusal (dns or policy) instead of callers
  inferring it from a missing cause; an empty DNS answer is ENOTFOUND
- the token check judges every DNS record when an environment proxy will
  carry the request, so a mixed public/private host is refused up front
  rather than failing in the transport as a retryable 502; the transport's
  own refusal is a typed EgressRefusedError and maps the same way
- new host_not_allowed code (400) with its own connect-modal message
- Flow and GitLab personal-token verification classify a refused or
  missing host the same way
- the typed-URL scheme guard is shared and ignores the tabs and newlines
  the URL parser drops
An oversized 2xx token reply carried status 200 into provider_unavailable
and its logs. A refusal keeps its own status.
run.version, async and waitTimeoutSeconds refuse read-only keys; the meta
example lists search:read with the full-access scopes.
Every listed tool is an internal operation, so the probed-request fallback
no longer builds or consults it.
The unauthenticated CLI poll route and the settings routes returned the
raw error message for an internal failure. Return a fixed message and keep
the cause in the server log; a conflict still names the existing key. The
CLI's comment now says a 400 can also be a refused key creation.
… rollback

The route-cache clear stays non-fatal but warns when it fails for any
reason other than a missing build id or cache. The api-key-read-only flag
says to revoke or replace read-only keys before rolling back.
The token route refused only session callers; any other auth type would
have been handed a saved secret. Allow internal JWT and refuse the rest.

Tools never execute in the browser (the registry boundary keeps the tool
registry out of every workspace client graph, and nothing else imports the
executor), so the browser-only token fetch through the route is deleted.
A cleared field arrived as '' and was sent as 0, a crawl of the start page
only. It now follows the blank maxDepth handling.
…of credential display

The JWKS route still answers 404 when the signing key is broken, but warns
with the error. The GitLab personal-token display reads its block type
from the catalog entry instead of importing the generated successor map
into a client-imported module.
- delegation: the read-only replacement case decided its filter by
  scanning bound params in a fake DB; no real-boundary check exists, so
  it is dropped with the fake's filter
- Twilio: assert how many recordings requests were sent, so an empty
  loop cannot pass
- Pi: the removed-model case restated the absent-from-catalog case
10.0.0.0/8/junk parsed as /8. An entry with extra segments is dropped like
any other unparseable entry, and the TSDoc says IP entries match within
their address family.
… the mutability guard

- the execution-status paused-row read filters by workflowId as well
- delete-workflow uses requireMutableWorkflow instead of an inline copy
- polling webhook logs carry the webhook id in metadata
…fusal

The caller may not be able to see the credential that holds or blocks the
subject, so both refusals name only the workspace or organization. The
uniqueness check documents its limits.
@vercel

vercel Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Nov 11, 2026 1:11am UTC

Request Review

@greptile-apps

greptile-apps Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The PR appears safe to merge; no new actionable issues remain.

Summary

This PR tightens credential release and improves errors for refused hosts.

  • Credential checks now tell refused hosts apart from missing sites and outages.
  • Only internal-JWT callers can receive saved service-account secrets.
  • API-key checks accept nullable ban states and explain which keys can run workflows.
  • API-key creation gives callers a generic message for internal failures.
  • Keyless trust refusals no longer name credentials the caller may not see.
  • Oversized successful Databricks token replies report a gateway error.
  • Redaction keeps Infisical secret names visible while masking credential keys.
  • Firecrawl treats a blank discovery depth as unset.
  • Workflow status reads stay scoped to their workflow, and deletion uses the shared mutability check.
  • Credential contract checks include destination-like fields for operation tools.
  • Operators get clearer logs when route-cache or webhook updates fail.
  • Small boundary, test, and deployment-note cleanups leave product behavior unchanged.

The previous AWS-secret logging finding is fixed: the current pattern masks bedrockSecretKey and other prefixed secret keys.

Reviews (3) · Last reviewed commit: "fix(release): keep bare secretKey redact..." · Reviewed by Greptile

Comment thread apps/sim/lib/core/security/redaction.ts Resolved
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 53 files

Reply with feedback, questions, or to request a fix.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/lib/core/security/redaction.ts Resolved
Comment thread apps/sim/lib/core/utils/route-cache.ts Resolved
…ress rule to the transport, and report unknown GitLab hosts as input errors
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 54 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Turn on auto-fix | Re-trigger cubic

This branch was previously deployed

1 inactive deployment
Preview — 17cf2df4 Deployed Nov 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant