Skip to content

fix(guardrails): authorize vertexCredential before use in hallucination validation#5400

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix-guardrails-vertex-cred-authz
Jul 3, 2026
Merged

fix(guardrails): authorize vertexCredential before use in hallucination validation#5400
waleedlatif1 merged 2 commits into
stagingfrom
fix-guardrails-vertex-cred-authz

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • The guardrails validate route now authorizes a caller-supplied vertexCredential via authorizeCredentialUse before it's used in hallucination validation, matching the existing check already used in the providers route for the same field.
  • Added route test coverage for the new gate: rejects inaccessible credentials, allows accessible ones, and leaves non-vertex/no-credential requests unaffected.

Type of Change

  • Bug fix

Testing

  • Added apps/sim/app/api/guardrails/validate/route.test.ts covering the new authorization gate.
  • bun run vitest run app/api/guardrails/validate/route.test.ts passes (4/4).
  • Typecheck and biome clean on touched files.

Checklist

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

…on validation

The guardrails validate route now checks credential access via
authorizeCredentialUse before passing a caller-supplied vertexCredential
into hallucination validation, matching the existing pattern already used
in the providers route for the same field.
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 3, 2026 10:17pm

Request Review

@cursor

cursor Bot commented Jul 3, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches auth on a public API path that forwards credentials into LLM/RAG work; the change reduces credential misuse risk with narrow, provider-scoped checks.

Overview
Closes a gap where callers could pass another user’s vertexCredential into hallucination guardrail validation without an ownership check.

The validate route now calls authorizeCredentialUse (same pattern as other credential-bearing APIs) only when both vertexCredential is set and getProviderFromModel(model) is vertex, returning 401 before validateHallucination runs. Non-hallucination types, missing credentials, and hallucination with non-Vertex models skip this gate.

Adds route.test.ts covering deny/allow paths and the cases where authorization is not invoked.

Reviewed by Cursor Bugbot for commit 9f8e410. Configure here.

Comment thread apps/sim/app/api/guardrails/validate/route.ts
@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a missing authorization gate in the guardrails validate route: a caller-supplied vertexCredential was being forwarded to validateHallucination without first checking whether the caller has access to that credential. The fix mirrors the pattern already used in the providers route for the same field.

  • route.ts: Adds a authorizeCredentialUse check for vertexCredential after the usage-limit gate and before validateHallucination is called, conditioned on both vertexCredential being present and the resolved model being 'vertex'.
  • route.test.ts: New test file covering the authorization gate — denies inaccessible credentials (401), passes accessible credentials through, and leaves non-vertex or no-credential hallucination requests unaffected.

Confidence Score: 5/5

Safe to merge — the change is a targeted authorization guard that closes a credential-access gap without altering any validation logic or response shapes for existing callers.

The new gate is correctly placed (after workflow authz and usage limits, before the expensive LLM call), the condition is tight (only fires when both a vertexCredential is present and the resolved provider is 'vertex'), and the 401 response shape is consistent with the adjacent 402 pattern already present. Tests cover all five meaningful branches, and the implementation mirrors the same check in the providers route.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/api/guardrails/validate/route.ts Adds authorizeCredentialUse gate for vertexCredential before hallucination validation; placement and condition are correct, consistent with the providers route pattern.
apps/sim/app/api/guardrails/validate/route.test.ts New test file with 5 cases covering all branching conditions of the new credential gate (note: PR description says '4/4' but the file contains 5 tests — likely written before the final test was added).

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant C as Caller
    participant R as POST /api/guardrails/validate
    participant A as checkSessionOrInternalAuth
    participant W as authorizeWorkflowByWorkspacePermission
    participant P as assertPermissionsAllowed
    participant U as checkActorUsageLimits
    participant V as authorizeCredentialUse (NEW)
    participant H as validateHallucination

    C->>R: "POST { validationType: hallucination, vertexCredential, model: vertex/... }"
    R->>A: authenticate caller
    A-->>R: "{ success, userId }"
    R->>W: authorize workflow access
    W-->>R: "{ allowed, workspaceId }"
    R->>P: assertPermissionsAllowed(userId, workspaceId, model)
    P-->>R: ok / throws
    R->>U: checkActorUsageLimits(userId, workspaceId)
    U-->>R: "{ isExceeded }"
    alt isExceeded
        R-->>C: 402 usage limit
    end
    R->>V: "authorizeCredentialUse(req, { credentialId: vertexCredential, workflowId })"
    alt access denied
        V-->>R: "{ ok: false, error }"
        R-->>C: 401 Unauthorized
    else access granted
        V-->>R: "{ ok: true }"
        R->>H: validateHallucination(...)
        H-->>R: "{ passed, score, ... }"
        R-->>C: "200 { success, output }"
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant C as Caller
    participant R as POST /api/guardrails/validate
    participant A as checkSessionOrInternalAuth
    participant W as authorizeWorkflowByWorkspacePermission
    participant P as assertPermissionsAllowed
    participant U as checkActorUsageLimits
    participant V as authorizeCredentialUse (NEW)
    participant H as validateHallucination

    C->>R: "POST { validationType: hallucination, vertexCredential, model: vertex/... }"
    R->>A: authenticate caller
    A-->>R: "{ success, userId }"
    R->>W: authorize workflow access
    W-->>R: "{ allowed, workspaceId }"
    R->>P: assertPermissionsAllowed(userId, workspaceId, model)
    P-->>R: ok / throws
    R->>U: checkActorUsageLimits(userId, workspaceId)
    U-->>R: "{ isExceeded }"
    alt isExceeded
        R-->>C: 402 usage limit
    end
    R->>V: "authorizeCredentialUse(req, { credentialId: vertexCredential, workflowId })"
    alt access denied
        V-->>R: "{ ok: false, error }"
        R-->>C: 401 Unauthorized
    else access granted
        V-->>R: "{ ok: true }"
        R->>H: validateHallucination(...)
        H-->>R: "{ passed, score, ... }"
        R-->>C: "200 { success, output }"
    end
Loading

Reviews (2): Last reviewed commit: "fix(guardrails): gate vertexCredential a..." | Re-trigger Greptile

Comment thread apps/sim/app/api/guardrails/validate/route.ts
Comment thread apps/sim/app/api/guardrails/validate/route.ts
…provider

Only run the credential check when the model actually resolves to vertex,
matching the providers route's gating exactly, and drop a redundant
fallback now that workflowId is already guaranteed present at that point.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 9f8e410. Configure here.

@waleedlatif1 waleedlatif1 merged commit ff8844c into staging Jul 3, 2026
13 checks passed
@waleedlatif1 waleedlatif1 deleted the fix-guardrails-vertex-cred-authz branch July 3, 2026 22:20
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