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
The OAuth consent-URL safety gate introduced in #1328 (oauth_url_contains_credential in src/kiro_crew/security.py) trusts an exact-match allowlist of hardcoded (host, path) pairs. Any identity provider outside that frozen set has its consent URL rejected, so the Connections banner shows a generic authentication failure with no operator escape hatch short of a code release.
Providers currently excluded include:
Okta (<tenant>.okta.com/oauth2/v1/authorize)
Auth0 (<tenant>.auth0.com/authorize)
Self-hosted OIDC of any kind
Tenant-scoped Microsoft — only login.microsoftonline.com/common/oauth2/v2.0/authorize is listed, but many organisation app registrations require /{tenant}/oauth2/v2.0/authorize, which exact-path matching excludes
Two related specifics worth recording rather than rediscovering:
Non-allowlisted providers do not merely miss the exemption — they then trip the ≥200-character query heuristic, because real consent URLs routinely exceed it. So the failure mode is an unhelpful "authentication failed", not a clear "unsupported provider".
fix(security): stop redacting OAuth consent URLs without weakening secret detection #1328removed a previously-passing corpus case (a generic id.example-idp.com long-state URL) from test/oauth_url_corpus.py, because the narrowed gate no longer passes it. That deletion documents the regression rather than hiding it, but the case should come back once the allowlist can be extended.
Why
The narrowing was deliberate and is the safe direction: it closes a real exfiltration channel where a state= parameter on an attacker-controlled host could carry a credential past redaction and render as a clickable Authorize link. It also fails closed — an unsupported provider degrades to "cannot authenticate", never to a leaked secret.
There is no impact on the current launch set: M1 ships exactly the six registry providers (notion, github, linear, atlassian, stripe, vercel), all allowlisted. The cost lands the moment anyone connects an MCP server fronted by their own IdP — which, for an open MCP ecosystem, is a matter of when rather than if. At that point the only remedy is a KiroCrew release, which is the wrong shape for what is really operator configuration.
Additional Context
Raised by the advisory design review on #1328 (Design-Verdict: CONCERNS), and deliberately deferred with the decision to ship narrow for M1 rather than grow the PR.
Suggested direction from that review, recorded so the design intent is not lost:
Add an operator-owned allowlist extension using the repo's existing keystone pattern — a file fenced like computer_use.json so the agent cannot widen its own trust boundary, while an operator can add an IdP without waiting for a release.
Reject non-allowlisted endpoints with a message that names the endpoint and the extension path, so users can tell "unsupported IdP" apart from "tampered URL".
Restore the generic-IdP corpus case in test/oauth_url_corpus.py once the extension exists.
Tracked in the design doc under Workstream E / open items so this does not live only in an issue.
Related: #1328 (the narrowing), #1287 (provider registry), #1229 (Connections page).
What
The OAuth consent-URL safety gate introduced in #1328 (
oauth_url_contains_credentialinsrc/kiro_crew/security.py) trusts an exact-match allowlist of hardcoded(host, path)pairs. Any identity provider outside that frozen set has its consent URL rejected, so the Connections banner shows a generic authentication failure with no operator escape hatch short of a code release.Providers currently excluded include:
<tenant>.okta.com/oauth2/v1/authorize)<tenant>.auth0.com/authorize)login.microsoftonline.com/common/oauth2/v2.0/authorizeis listed, but many organisation app registrations require/{tenant}/oauth2/v2.0/authorize, which exact-path matching excludesTwo related specifics worth recording rather than rediscovering:
id.example-idp.comlong-stateURL) fromtest/oauth_url_corpus.py, because the narrowed gate no longer passes it. That deletion documents the regression rather than hiding it, but the case should come back once the allowlist can be extended.Why
The narrowing was deliberate and is the safe direction: it closes a real exfiltration channel where a
state=parameter on an attacker-controlled host could carry a credential past redaction and render as a clickable Authorize link. It also fails closed — an unsupported provider degrades to "cannot authenticate", never to a leaked secret.There is no impact on the current launch set: M1 ships exactly the six registry providers (
notion,github,linear,atlassian,stripe,vercel), all allowlisted. The cost lands the moment anyone connects an MCP server fronted by their own IdP — which, for an open MCP ecosystem, is a matter of when rather than if. At that point the only remedy is a KiroCrew release, which is the wrong shape for what is really operator configuration.Additional Context
Raised by the advisory design review on #1328 (Design-Verdict: CONCERNS), and deliberately deferred with the decision to ship narrow for M1 rather than grow the PR.
Suggested direction from that review, recorded so the design intent is not lost:
computer_use.jsonso the agent cannot widen its own trust boundary, while an operator can add an IdP without waiting for a release.test/oauth_url_corpus.pyonce the extension exists.Tracked in the design doc under Workstream E / open items so this does not live only in an issue.
Related: #1328 (the narrowing), #1287 (provider registry), #1229 (Connections page).