Skip to content

feat: add compatability with gatus security.basic#21

Open
z0xca wants to merge 3 commits into
sparanoid:masterfrom
z0xca:master
Open

feat: add compatability with gatus security.basic#21
z0xca wants to merge 3 commits into
sparanoid:masterfrom
z0xca:master

Conversation

@z0xca

@z0xca z0xca commented Jul 1, 2026

Copy link
Copy Markdown

This PR adds the ability for STS to authenticate with Gatus via security.basic, which is useful for people that want to only expose STS publicly and not Gatus

Summary by CodeRabbit

  • New Features

    • Added support for authenticating with a protected Gatus API using optional username and password environment variables.
    • Requests now include a clearer user agent identifier.
  • Documentation

    • Updated configuration docs for environment variables and improved formatting for clarity.
@vercel

vercel Bot commented Jul 1, 2026

Copy link
Copy Markdown

@z0xca is attempting to deploy a commit to the Sparanoid Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@z0xca, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 603a1cd1-b3fd-42e3-97bd-871a0afa1ec1

📥 Commits

Reviewing files that changed from the base of the PR and between 21af415 and 0a3889f.

📒 Files selected for processing (1)
  • lib/getStatuses.ts
📝 Walkthrough

Walkthrough

Adds optional GATUS_API_USERNAME and GATUS_API_PASSWORD environment variables for authenticating against a Basic Auth-protected Gatus API. Updates getStatuses.ts to build headers conditionally including an Authorization header when credentials are present. Updates README.md configuration table formatting.

Changes

Gatus API Basic Auth

Layer / File(s) Summary
Basic auth header construction and credentials
.env.example, lib/getStatuses.ts
Adds optional GATUS_API_USERNAME/GATUS_API_PASSWORD placeholders and builds a HeadersInit with a User-Agent header, conditionally adding a base64-encoded Authorization: Basic header when both credentials are set.
Configuration documentation
README.md
Reformats the environment-variable configuration table, standardizing spacing/alignment and updating description text (e.g., GATUS_API_BASE example punctuation).

Estimated code review effort: 2 (Simple) | ~10 minutes

Sequence Diagram(s)

sequenceDiagram
  participant getStatuses
  participant Env as process.env
  participant GatusAPI

  getStatuses->>Env: read GATUS_API_USERNAME, GATUS_API_PASSWORD
  alt credentials present
    getStatuses->>getStatuses: base64 encode username:password
    getStatuses->>GatusAPI: fetch with Authorization header
  else credentials absent
    getStatuses->>GatusAPI: fetch with User-Agent header only
  end
Loading

Related Issues: None specified.

Related PRs: None specified.

Suggested labels: documentation, enhancement

Suggested reviewers: sparanoid

🐰 A carrot of credentials, base64 tucked in tight,
Gatus opens gently to the header's polite might.
README rows aligned in neat little seams,
Basic auth hops in — securing all our streams. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding Gatus security.basic compatibility for authentication.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add optional Basic Auth when querying Gatus API

✨ Enhancement 📝 Documentation ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Add optional HTTP Basic Auth header for Gatus API requests via env vars.
• Document new GATUS_API_USERNAME/PASSWORD variables and update .env.example.
• Keep existing unauthenticated behavior when credentials are not provided.
Diagram

graph TD
  A["STS server"] --> B["getStatuses()"] --> C["Build headers"] --> D["Fetch /endpoints/statuses"] --> E["Gatus API"]
  F["Env: GATUS_API_USERNAME/PASSWORD"] --> C
Loading
High-Level Assessment

The chosen approach (conditionally attaching a Basic Authorization header based on env vars) is the simplest and most compatible way to support Gatus security.basic without affecting existing deployments. Alternatives like relying on a reverse proxy for auth or adding a different auth scheme would be broader in scope and less directly aligned with Gatus' Basic Auth configuration.

Files changed (3) +30 / -17

Enhancement (1) +10 / -3
getStatuses.tsSend Basic Auth header to Gatus when credentials are configured +10/-3

Send Basic Auth header to Gatus when credentials are configured

• Builds a 'headers' object including the existing User-Agent and conditionally sets 'Authorization: Basic ...' when both 'GATUS_API_USERNAME' and 'GATUS_API_PASSWORD' are present. Uses the shared headers object in the fetch call to Gatus statuses.

lib/getStatuses.ts

Documentation (1) +16 / -14
README.mdDocument new Gatus username/password environment variables +16/-14

Document new Gatus username/password environment variables

• Updates the environment variable table to include 'GATUS_API_USERNAME' and 'GATUS_API_PASSWORD' as optional settings for authenticating to the Gatus API.

README.md

Other (1) +4 / -0
.env.exampleAdd optional Gatus Basic Auth env placeholders +4/-0

Add optional Gatus Basic Auth env placeholders

• Adds 'GATUS_API_USERNAME' and 'GATUS_API_PASSWORD' to document optional credentials when Gatus is protected via 'security.basic'.

.env.example

@qodo-code-review

qodo-code-review Bot commented Jul 1, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. HeadersInit type misuse ✓ Resolved 🐞 Bug ≡ Correctness
Description
getStatuses() declares headers as HeadersInit and then mutates it via `headers.Authorization =
..., which is not valid for the HeadersInit` union type under the repo’s strict TypeScript
settings. This is likely to fail compilation and block builds.
Code

lib/getStatuses.ts[R13-20]

+  const headers: HeadersInit = {
+    "User-Agent": `sparanoid-sts/${version}`,
+  };
+
+  const { GATUS_API_USERNAME, GATUS_API_PASSWORD } = process.env;
+  if (GATUS_API_USERNAME && GATUS_API_PASSWORD) {
+    headers.Authorization = `Basic ${Buffer.from(`${GATUS_API_USERNAME}:${GATUS_API_PASSWORD}`).toString("base64")}`;
+  }
Evidence
The PR change types headers as HeadersInit and then assigns a new property (Authorization),
which is not allowed on the HeadersInit union in strict TS. The repo’s tsconfig.json explicitly
enables strict: true, making this a build-time correctness problem.

lib/getStatuses.ts[13-20]
tsconfig.json[1-15]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`headers` is typed as `HeadersInit` (a union type), but later the code assigns `headers.Authorization = ...`. With `strict: true`, this should be a TypeScript error and can break `next build`.

### Issue Context
This code runs in `lib/getStatuses.ts` when building request headers for the Gatus API.

### Fix Focus Areas
- lib/getStatuses.ts[13-20]

### Suggested fix
Prefer one of these:
1) Use a plain object type:
```ts
const headers: Record<string, string> = {
 'User-Agent': `sparanoid-sts/${version}`,
}
if (GATUS_API_USERNAME && GATUS_API_PASSWORD) {
 headers.Authorization = `Basic ${Buffer.from(`${GATUS_API_USERNAME}:${GATUS_API_PASSWORD}`).toString('base64')}`
}
```

2) Or use the `Headers` class:
```ts
const headers = new Headers({
 'User-Agent': `sparanoid-sts/${version}`,
})
if (GATUS_API_USERNAME && GATUS_API_PASSWORD) {
 headers.set('Authorization', `Basic ${Buffer.from(`${GATUS_API_USERNAME}:${GATUS_API_PASSWORD}`).toString('base64')}`)
}
```
Either option avoids mutating a `HeadersInit`-typed union.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread lib/getStatuses.ts Outdated
@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds HTTP Basic authentication support for protected Gatus API instances by reading GATUS_API_USERNAME and GATUS_API_PASSWORD from environment variables and constructing a Basic Authorization header when both are present. Documentation and .env.example are updated accordingly.

  • lib/getStatuses.ts: Reads the two new env vars and, when both are non-empty, base64-encodes username:password via Buffer and injects it as an Authorization header; also explicitly types headers as Record<string, string> (addressing a prior type-safety concern).
  • .env.example / README.md: Document the two new optional env vars with correct formatting and ordering.

Confidence Score: 5/5

Safe to merge — the auth header is constructed entirely server-side from env vars, credentials are never exposed to the client, and the change is well-scoped to a single fetch utility.

The implementation is straightforward: Buffer.from(user:pass).toString('base64') is the correct way to produce a Basic auth token in Node.js, the explicit Record<string, string> type addresses the prior type-safety concern, and the guard correctly skips auth when credentials are absent. No regressions to existing behaviour.

No files require special attention.

Important Files Changed

Filename Overview
lib/getStatuses.ts Adds Basic auth header construction using Buffer.from() when both username and password env vars are set; typed as Record<string, string> which is correct and safe.
.env.example Adds blank GATUS_API_USERNAME and GATUS_API_PASSWORD entries with a descriptive comment; straightforward and correct.
README.md Documents the two new optional env vars in the configuration table; minor formatting improvements are a nice cleanup.

Reviews (2): Last reviewed commit: "Update lib/getStatuses.ts" | Re-trigger Greptile

Comment thread lib/getStatuses.ts Outdated
Comment thread lib/getStatuses.ts
Comment on lines +18 to +20
if (GATUS_API_USERNAME && GATUS_API_PASSWORD) {
headers.Authorization = `Basic ${Buffer.from(`${GATUS_API_USERNAME}:${GATUS_API_PASSWORD}`).toString("base64")}`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Silent auth skip with partial credentials

If a user sets GATUS_API_USERNAME but forgets GATUS_API_PASSWORD (or vice versa), no Authorization header is sent and the request will silently return a 401 from Gatus (surfaced only as the generic 'Failed to fetch data' error). A console warning when exactly one variable is present would make misconfiguration much easier to diagnose.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.env.example:
- Around line 25-27: The GATUS credential entries in the env template are in the
wrong order for dotenv-linter. Reorder the two variables in the .env.example
block so the password key comes before the username key, keeping the existing
names and values empty; this is the only change needed.

In `@lib/getStatuses.ts`:
- Around line 13-23: The headers object in getStatuses is being mutated after
being declared as HeadersInit, which does not support direct property assignment
for Authorization. Update the getStatuses function to build headers as a mutable
Record<string, string> (or use a Headers instance and call set()), then keep the
existing Basic auth assignment and fetch call using that same headers variable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c1959d2e-462e-4d35-b5f1-b7f33789ddcd

📥 Commits

Reviewing files that changed from the base of the PR and between dae210f and 21af415.

📒 Files selected for processing (3)
  • .env.example
  • README.md
  • lib/getStatuses.ts
Comment thread .env.example
Comment thread lib/getStatuses.ts Outdated
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant