Skip to content

Guardrails: Authentication Fixes#120

Merged
AkhileshNegi merged 2 commits intomainfrom
fix/guardrails-authentication
Apr 18, 2026
Merged

Guardrails: Authentication Fixes#120
AkhileshNegi merged 2 commits intomainfrom
fix/guardrails-authentication

Conversation

@Ayush8923
Copy link
Copy Markdown
Collaborator

@Ayush8923 Ayush8923 commented Apr 18, 2026

Previous PR Reference: #116

Summary

  • X-API-KEY + access token forwarding in guardrailsFetch.
  • Guardrails page UI tweaks

@Ayush8923 Ayush8923 self-assigned this Apr 18, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 18, 2026

Warning

Rate limit exceeded

@Ayush8923 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 52 minutes and 8 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 52 minutes and 8 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c2dc562f-1e95-4831-899f-f6080ff7f23e

📥 Commits

Reviewing files that changed from the base of the PR and between a1a6e9f and eea3b4a.

📒 Files selected for processing (1)
  • app/components/guardrails/SavedConfigsList.tsx
📝 Walkthrough

Walkthrough

This PR integrates API key-based authentication throughout the guardrails components by extracting the active API key from the auth context and threading it through all guardrailsFetch calls. The central utility function now accepts an apiKey parameter and conditionally sets the X-API-KEY header, while effect dependencies are updated to re-run when the API key changes. One UI component also switches to using a Loader component for loading states.

Changes

Cohort / File(s) Summary
Auth Integration in Guardrails Components
app/(main)/guardrails/page.tsx, app/components/guardrails/BanListField.tsx, app/components/guardrails/BanListModal.tsx, app/components/prompt-editor/ConfigEditorPane.tsx
Extract apiKey from useAuth() and pass it to all guardrailsFetch calls. Update effect dependencies to re-run when apiKey changes, ensuring fetches are re-triggered on authentication state changes.
Core API Client Update
app/lib/guardrailsClient.ts
Update guardrailsFetch signature to accept apiKey parameter and conditionally set X-API-KEY header when the key is non-empty.
UI Refinement
app/components/guardrails/SavedConfigsList.tsx
Replace loading skeleton UI with centered Loader component and adjust saved-config item left border width from border-l-4 to border-l-2.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • Phase:2- Refactoring #91: Introduces auth hydration tracking and active API key management in AuthContext; this PR consumes those changes by threading the API key through guardrails API calls.

Suggested labels

ready-for-review

Suggested reviewers

  • vprashrex
  • Prajna1999

Poem

🐰 A key threaded through the guardrails flow,
Each fetch now knows which auth to show,
From context pulled to header set,
The API guards can't forget!
With loaders spinning, borders trim,
Authentication's looking bright and prim. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: adding API key authentication to guardrails fetch calls across multiple components.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/guardrails-authentication

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
app/components/guardrails/BanListField.tsx (1)

55-88: ⚠️ Potential issue | 🟠 Major

apiKey missing from effect dependencies — ban list/word fetches won't retry after auth hydrates.

fetchBanLists is invoked in a mount-only effect ([] on Line 80), and fetchBannedWords depends only on [value] (Line 88). Both close over apiKey, which is "" on the first render when activeKey hasn't populated yet. Once useAuth() hydrates and apiKey changes, neither effect re-runs, so the requests are permanently sent without X-API-KEY and the user sees "Failed to load ban lists" until a remount.

This is the most impactful issue in this PR — unlike guardrails/page.tsx, which correctly includes apiKey in its dep arrays, this component will be broken for users whose auth context isn't ready by mount.

Proposed fix
 useEffect(() => {
+  if (!apiKey) return;
   fetchBanLists();
-}, []);
+  // eslint-disable-next-line react-hooks/exhaustive-deps
+}, [apiKey]);

 useEffect(() => {
-  if (value) {
+  if (value && apiKey) {
     fetchBannedWords(value);
   } else {
     setBannedWords([]);
   }
-}, [value]);
+  // eslint-disable-next-line react-hooks/exhaustive-deps
+}, [value, apiKey]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/guardrails/BanListField.tsx` around lines 55 - 88, The effects
that call fetchBanLists and fetchBannedWords close over apiKey but do not
include it in their dependency arrays, so add apiKey to both useEffect deps (the
mount effect that currently calls fetchBanLists and the effect that calls
fetchBannedWords when value changes) so they re-run when auth hydrates; ensure
fetchBanLists and fetchBannedWords continue to read the apiKey param (or accept
apiKey as an explicit argument) so the requests include the correct X-API-KEY
after hydration.
app/(main)/guardrails/page.tsx (1)

60-71: ⚠️ Potential issue | 🟡 Minor

Validators load fires before auth is hydrated.

Unlike the verify effect above (Line 41), this effect has no isHydrated guard, so on first mount apiKey is "" and /api/guardrails is called without X-API-KEY. It will re-run once apiKey is set (dep array is correct), but the initial unauthenticated request is wasted and may toast "Failed to load validators" transiently. Consider gating on isHydrated and a non-empty apiKey:

Proposed fix
 useEffect(() => {
+  if (!isHydrated || !apiKey) return;
   setValidatorsLoading(true);
   guardrailsFetch<{ validators?: Validator[] }>("/api/guardrails", apiKey)
     ...
-}, [apiKey]);
+}, [isHydrated, apiKey]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/`(main)/guardrails/page.tsx around lines 60 - 71, The effect that loads
validators is firing before auth is hydrated; update the useEffect (the effect
that calls guardrailsFetch and uses setValidatorsLoading, setValidators) to bail
out unless isHydrated is true and apiKey is non-empty: add a guard at the top of
the effect that returns early when !isHydrated or apiKey === "" so the initial
unauthenticated request (and transient toast from guardrailsFetch .catch) is
avoided, keeping the rest of the logic (then/catch/finally) unchanged.
app/components/prompt-editor/ConfigEditorPane.tsx (1)

74-89: ⚠️ Potential issue | 🟡 Minor

Verify request may fire with an empty apiKey.

When the component mounts before auth is hydrated (or when the parent hasn't passed apiKey yet), this effect calls /api/apikeys/verify with apiKey="", resulting in an unauthenticated request. The effect will re-run when apiKey becomes non-empty, but the initial call is wasted. Consider early-returning when apiKey is empty:

Proposed fix
 useEffect(() => {
+  if (!apiKey) return;
   guardrailsFetch<{ data?: { organization_id: number; project_id: number } }>(
     "/api/apikeys/verify",
     apiKey,
   )
   ...
 }, [apiKey]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/prompt-editor/ConfigEditorPane.tsx` around lines 74 - 89, The
effect in ConfigEditorPane calls guardrailsFetch("/api/apikeys/verify", apiKey)
even when apiKey is empty; update the useEffect callback to early-return if
apiKey is falsy (e.g., empty string) before calling guardrailsFetch so no
unauthenticated request is sent, preserving the existing logic that
setsGuardrailsQueryString from the response once a valid apiKey is available.
🧹 Nitpick comments (1)
app/lib/guardrailsClient.ts (1)

63-72: Consider making apiKey optional for ergonomics.

Changing apiKey to a required positional string forces every caller to explicitly pass "" when no key is available (and already several call sites do activeKey?.key ?? ""). Making it optional (apiKey?: string) would be equivalent at runtime (the if (apiKey) guard already handles falsy values) and reduce noise at call sites. Non-blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/lib/guardrailsClient.ts` around lines 63 - 72, The function
guardrailsFetch currently requires apiKey: string which forces callers to pass
empty strings; change the signature to apiKey?: string so the parameter is
optional (the existing if (apiKey) guard and headers.set("X-API-KEY", apiKey)
behavior remain correct), update any TypeScript usages/types accordingly, and
run a quick grep for guardrailsFetch call sites to remove redundant ?? "" where
present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@app/`(main)/guardrails/page.tsx:
- Around line 60-71: The effect that loads validators is firing before auth is
hydrated; update the useEffect (the effect that calls guardrailsFetch and uses
setValidatorsLoading, setValidators) to bail out unless isHydrated is true and
apiKey is non-empty: add a guard at the top of the effect that returns early
when !isHydrated or apiKey === "" so the initial unauthenticated request (and
transient toast from guardrailsFetch .catch) is avoided, keeping the rest of the
logic (then/catch/finally) unchanged.

In `@app/components/guardrails/BanListField.tsx`:
- Around line 55-88: The effects that call fetchBanLists and fetchBannedWords
close over apiKey but do not include it in their dependency arrays, so add
apiKey to both useEffect deps (the mount effect that currently calls
fetchBanLists and the effect that calls fetchBannedWords when value changes) so
they re-run when auth hydrates; ensure fetchBanLists and fetchBannedWords
continue to read the apiKey param (or accept apiKey as an explicit argument) so
the requests include the correct X-API-KEY after hydration.

In `@app/components/prompt-editor/ConfigEditorPane.tsx`:
- Around line 74-89: The effect in ConfigEditorPane calls
guardrailsFetch("/api/apikeys/verify", apiKey) even when apiKey is empty; update
the useEffect callback to early-return if apiKey is falsy (e.g., empty string)
before calling guardrailsFetch so no unauthenticated request is sent, preserving
the existing logic that setsGuardrailsQueryString from the response once a valid
apiKey is available.

---

Nitpick comments:
In `@app/lib/guardrailsClient.ts`:
- Around line 63-72: The function guardrailsFetch currently requires apiKey:
string which forces callers to pass empty strings; change the signature to
apiKey?: string so the parameter is optional (the existing if (apiKey) guard and
headers.set("X-API-KEY", apiKey) behavior remain correct), update any TypeScript
usages/types accordingly, and run a quick grep for guardrailsFetch call sites to
remove redundant ?? "" where present.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b0468bf2-93db-48db-8e44-4ed1e967b960

📥 Commits

Reviewing files that changed from the base of the PR and between 72c8a91 and a1a6e9f.

📒 Files selected for processing (6)
  • app/(main)/guardrails/page.tsx
  • app/components/guardrails/BanListField.tsx
  • app/components/guardrails/BanListModal.tsx
  • app/components/guardrails/SavedConfigsList.tsx
  • app/components/prompt-editor/ConfigEditorPane.tsx
  • app/lib/guardrailsClient.ts

@Ayush8923 Ayush8923 requested a review from nishika26 April 18, 2026 06:22
@AkhileshNegi AkhileshNegi merged commit a52ee8e into main Apr 18, 2026
2 checks passed
@AkhileshNegi AkhileshNegi deleted the fix/guardrails-authentication branch April 18, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants