Skip to content

Add header auth and access restrictions to reverse proxy#583

Closed
lixmal wants to merge 4 commits intomainfrom
feature/reverse-proxy-auth
Closed

Add header auth and access restrictions to reverse proxy#583
lixmal wants to merge 4 commits intomainfrom
feature/reverse-proxy-auth

Conversation

@lixmal
Copy link
Copy Markdown
Contributor

@lixmal lixmal commented Mar 12, 2026

Add UI for configuring header-based authentication, geo/IP access restrictions, and session idle timeouts on reverse proxy services. Includes auth header modal, access restrictions section, and updated event display for auth/location metadata.

image image

Depends on netbirdio/netbird#5587

Summary by CodeRabbit

  • New Features

    • Access restrictions: configure CIDR and country allowlists/blocklists for reverse proxies.
    • Header-based authentication: add/manage HTTP header auth entries via modal.
    • Access Control UI: new tab and badges to view/configure access restrictions.
    • Target workflow: redesigned target editor with CIDR-aware host handling and two-step flow.
  • Improvements

    • Enhanced regional information: events include subdivision codes for more precise locations.
    • Removed session idle timeout upper limit for greater flexibility.
    • Auth visuals: richer badges and labels reflecting header/IP/country restrictions.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5488b4a4-629d-4290-9e4b-5d3f3ec20aa8

📥 Commits

Reviewing files that changed from the base of the PR and between ff8efd4 and 0844507.

📒 Files selected for processing (10)
  • src/contexts/CountryProvider.tsx
  • src/interfaces/ReverseProxy.ts
  • src/modules/reverse-proxy/AccessRestrictionsSection.tsx
  • src/modules/reverse-proxy/ReverseProxyModal.tsx
  • src/modules/reverse-proxy/auth/AuthHeaderModal.tsx
  • src/modules/reverse-proxy/events/ReverseProxyEventsAuthMethodCell.tsx
  • src/modules/reverse-proxy/events/ReverseProxyEventsLocationIpCell.tsx
  • src/modules/reverse-proxy/table/ReverseProxyAuthCell.tsx
  • src/modules/reverse-proxy/targets/ReverseProxyTargetModal.tsx
  • src/modules/reverse-proxy/targets/useReverseProxyTargetOptions.ts
✅ Files skipped from review due to trivial changes (2)
  • src/modules/reverse-proxy/events/ReverseProxyEventsAuthMethodCell.tsx
  • src/modules/reverse-proxy/AccessRestrictionsSection.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/modules/reverse-proxy/targets/useReverseProxyTargetOptions.ts
  • src/modules/reverse-proxy/events/ReverseProxyEventsLocationIpCell.tsx

📝 Walkthrough

Walkthrough

Adds header-based HTTP auth, CIDR/country access-restrictions, and subdivision-aware region text to reverse-proxy types, UI modals, and event rendering; updates target/timeouts, target selection, and related badges/hover UI across reverse-proxy components.

Changes

Cohort / File(s) Summary
Region Lookup
src/contexts/CountryProvider.tsx, src/modules/reverse-proxy/events/ReverseProxyEventsLocationIpCell.tsx
Expanded getRegionText signature to accept optional subdivision_code; provider builds comma-joined parts (country, subdivision, city); event cell passes event.subdivision_code and updates memo deps.
Type Extensions
src/interfaces/ReverseProxy.ts
Added access_restrictions?: AccessRestrictions, header_auths?: HeaderAuthConfig[], and subdivision_code?: string on events; introduced HeaderAuthConfig and AccessRestrictions interfaces.
Access Restrictions UI
src/modules/reverse-proxy/AccessRestrictionsSection.tsx
New component managing CIDR allow/block and country allow/block lists with per-row state, validation (CIDR), add/remove, and onChange propagation.
Header Auth UI
src/modules/reverse-proxy/auth/AuthHeaderModal.tsx
New modal for managing header auth entries with presets (Basic/Bearer/Custom), draft lifecycle, validation, existing-secret handling, and conversion to/from API shape.
Modal & State Integration
src/modules/reverse-proxy/ReverseProxyModal.tsx
Major refactor: domain parsing, endpointMode state, TLS/L4 target state, request/session timeout split, header_auths and accessRestrictions state, Access Control tab, header-auth modal wiring, fetches for peers/resources, payload changes on submit, and no-protection confirmation updates.
Auth Badge & Access Cell
src/modules/reverse-proxy/table/ReverseProxyAuthCell.tsx, src/modules/reverse-proxy/events/ReverseProxyEventsAuthMethodCell.tsx
ReverseProxyAuthCell now counts header auth toward enabled methods, renders Header Auth badge, and shows L4AccessBadge with hover details from access_restrictions; events cell adds auth-method cases (header, ip_restricted, country_restricted, geo_unavailable) and icons.
Targets & Timeouts
src/modules/reverse-proxy/targets/ReverseProxyTargetModal.tsx, src/modules/reverse-proxy/targets/useReverseProxyTargetOptions.ts
Target modal reworked to tabbed flow, resource/peer fetching, CIDR-aware host editing/validation, mode-aware session idle timeout visibility; removed max-duration enforcement and made timeout validators file-local.
Events / Small Integrations
src/modules/reverse-proxy/events/..., src/modules/reverse-proxy/...
Various updates to pass subdivision_code, include access_restrictions in UI flows, and wire new header auth/access features into existing components.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Modal as ReverseProxyModal
    participant HeaderModal as AuthHeaderModal
    participant AccessSection as AccessRestrictionsSection
    participant API as API

    User->>Modal: Open reverse-proxy config
    User->>Modal: Open Header Auth
    Modal->>HeaderModal: open(currentHeaders)
    HeaderModal->>HeaderModal: validate drafts
    User->>HeaderModal: Save
    HeaderModal->>Modal: onSave(HeaderAuthConfig[])
    Modal->>Modal: update header_auths state

    User->>Modal: Open Access tab
    Modal->>AccessSection: render(currentRestrictions)
    User->>AccessSection: edit CIDR/country rows
    AccessSection->>Modal: onChange(AccessRestrictions)
    Modal->>Modal: update accessRestrictions state

    User->>Modal: Submit
    Modal->>API: POST/PUT payload with header_auths & access_restrictions
    API-->>Modal: OK
Loading
sequenceDiagram
    participant Viewer as User
    participant AuthCell as ReverseProxyAuthCell
    participant Badge as L4AccessBadge
    participant Modal as ReverseProxyModal

    Viewer->>AuthCell: View auth cell
    AuthCell->>AuthCell: compute totalEnabled (including header_auths)
    alt totalEnabled > 1
        AuthCell->>Viewer: show stacked badges
    else only header auth
        AuthCell->>Viewer: show Header Auth badge
    end

    alt access_restrictions present
        AuthCell->>Badge: render Access Control badge
        Viewer->>Badge: hover
        Badge->>Viewer: show allowed/blocked lists
        Viewer->>Badge: click Configure
        Badge->>Modal: open Access tab
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • pascal-fischer
  • heisbrot
  • mlsmaycon

Poem

🐰 Hopped through headers, CIDRs, and maps with a cheer,

Subdivisions and badges make regions clear.
Modal doors opened, secrets kept snug,
Access and auth snug as a bug.
Config saved — carrot cake, celebrate with a hug! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main changes: adding header auth and access restrictions to the reverse proxy feature.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/reverse-proxy-auth
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@lixmal
Copy link
Copy Markdown
Contributor Author

lixmal commented Mar 13, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/modules/reverse-proxy/AccessRestrictionsSection.tsx (1)

42-50: CIDR validation shows errors but doesn't block submission.

Invalid CIDR entries display an error message but are still propagated to the parent via onChange. Consider whether invalid entries should be filtered out or if validation should occur at the form submission level.

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

In `@src/modules/reverse-proxy/AccessRestrictionsSection.tsx` around lines 42 -
50, The CIDR check currently sets an error via setErrors when raw fails
cidr.isValidCIDR(raw) but still allows the invalid value to be propagated via
onChange; update the change handler so that when cidr.isValidCIDR(raw) is false
you do not call props.onChange (or you call onChange with the values list
filtered to exclude that id/raw), and when valid you clear the error and call
props.onChange with the updated valid CIDR list; locate the block using raw, id,
setErrors and cidr.isValidCIDR in AccessRestrictionsSection.tsx and adjust the
logic around the onChange invocation to only pass valid CIDRs (or explicitly
remove invalid entries) while preserving the existing setErrors behavior.
src/modules/reverse-proxy/ReverseProxyModal.tsx (1)

1174-1198: Consider adding a "Learn more" link for the Access Control tab.

The modal footer provides documentation links for the "targets", "auth", and "settings" tabs, but the new "access" tab doesn't have a corresponding link. If documentation exists for access restrictions, consider adding it for consistency.

Would you like me to help draft the code for adding the access control documentation link once the docs URL is available?

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

In `@src/modules/reverse-proxy/ReverseProxyModal.tsx` around lines 1174 - 1198,
Add a footer entry for the "access" tab similar to the existing blocks for
"auth" and "settings": when tab === "access" render a Paragraph containing an
InlineLink to the access docs (use a new constant like
REVERSE_PROXY_ACCESS_DOCS_LINK) and include the ExternalLinkIcon; follow the
same className ("text-sm mt-auto") and target={"_blank"} patterns used in the
"auth" and "settings" blocks so the modal footer remains consistent across tabs
and the link is only shown for the "access" tab.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/modules/reverse-proxy/AccessRestrictionsSection.tsx`:
- Around line 105-108: CountryList's local rows state (rows, setRows created in
CountryList via useState) is initialized from the values prop and will go stale
when values changes; update CountryList the same way as CidrList by making rows
reflect prop updates: initialize rows once from values but add a useEffect that
watches values and reconstructs setRows(values.map(v => ({ id: nextRowId++,
value: v }))) when values changes (ensuring nextRowId progression is preserved)
so the component stays in sync with the values prop.
- Around line 25-28: CidrList currently initializes internal rows state from the
values prop only on mount (see CidrList, rows, setRows, nextRowId), so it
becomes stale when the parent supplies new values; fix by syncing prop changes:
either update the parent to force remount with a stable unique key (e.g.,
key={`allowed-${reverseProxy.id}`} when rendering CidrList) or add a useEffect
inside CidrList that watches values and resets rows via setRows(values.map(v =>
({ id: nextRowId++, value: v }))) whenever values changes, ensuring the
displayed rows always reflect the latest prop.

In `@src/modules/reverse-proxy/auth/AuthHeaderModal.tsx`:
- Around line 143-145: The drafts state (useState initializer) only runs on
mount so when currentHeaders changes between modal opens the component remains
stale; update the component to synchronize drafts with currentHeaders by either
adding a key prop from the parent to force remount or adding a useEffect inside
AuthHeaderModal that watches currentHeaders and calls
setDrafts(currentHeaders.length > 0 ? currentHeaders.map(configToDraft) :
[newDraft()]) to reset drafts; reference the drafts/setDrafts state and
functions configToDraft and newDraft when implementing the fix.

---

Nitpick comments:
In `@src/modules/reverse-proxy/AccessRestrictionsSection.tsx`:
- Around line 42-50: The CIDR check currently sets an error via setErrors when
raw fails cidr.isValidCIDR(raw) but still allows the invalid value to be
propagated via onChange; update the change handler so that when
cidr.isValidCIDR(raw) is false you do not call props.onChange (or you call
onChange with the values list filtered to exclude that id/raw), and when valid
you clear the error and call props.onChange with the updated valid CIDR list;
locate the block using raw, id, setErrors and cidr.isValidCIDR in
AccessRestrictionsSection.tsx and adjust the logic around the onChange
invocation to only pass valid CIDRs (or explicitly remove invalid entries) while
preserving the existing setErrors behavior.

In `@src/modules/reverse-proxy/ReverseProxyModal.tsx`:
- Around line 1174-1198: Add a footer entry for the "access" tab similar to the
existing blocks for "auth" and "settings": when tab === "access" render a
Paragraph containing an InlineLink to the access docs (use a new constant like
REVERSE_PROXY_ACCESS_DOCS_LINK) and include the ExternalLinkIcon; follow the
same className ("text-sm mt-auto") and target={"_blank"} patterns used in the
"auth" and "settings" blocks so the modal footer remains consistent across tabs
and the link is only shown for the "access" tab.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fb78a0f-ca19-4e7f-a330-4b50e1b58b3e

📥 Commits

Reviewing files that changed from the base of the PR and between e02c507 and ff8efd4.

📒 Files selected for processing (10)
  • src/contexts/CountryProvider.tsx
  • src/interfaces/ReverseProxy.ts
  • src/modules/reverse-proxy/AccessRestrictionsSection.tsx
  • src/modules/reverse-proxy/ReverseProxyModal.tsx
  • src/modules/reverse-proxy/auth/AuthHeaderModal.tsx
  • src/modules/reverse-proxy/events/ReverseProxyEventsAuthMethodCell.tsx
  • src/modules/reverse-proxy/events/ReverseProxyEventsLocationIpCell.tsx
  • src/modules/reverse-proxy/table/ReverseProxyAuthCell.tsx
  • src/modules/reverse-proxy/targets/ReverseProxyTargetModal.tsx
  • src/modules/reverse-proxy/targets/useReverseProxyTargetOptions.ts
💤 Files with no reviewable changes (1)
  • src/modules/reverse-proxy/targets/useReverseProxyTargetOptions.ts

Comment thread src/modules/reverse-proxy/AccessRestrictionsSection.tsx
Comment thread src/modules/reverse-proxy/AccessRestrictionsSection.tsx
Comment thread src/modules/reverse-proxy/auth/AuthHeaderModal.tsx
@pascal-fischer
Copy link
Copy Markdown
Contributor

overall it looks good. The quick overview about auth and restrictions could be better I think. If I have restrictions but no auth it is not really detectable from the main view if just says 'none' (you need to know the difference between the 2 no tags)
screenshot-20260316-150744

Base automatically changed from feature/reverse-proxy to main March 18, 2026 16:43
@lixmal lixmal force-pushed the feature/reverse-proxy-auth branch from a48e071 to 0844507 Compare March 19, 2026 15:06
@heisbrot heisbrot closed this Mar 25, 2026
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.

3 participants