Skip to content

fix: redact credentials from a layer's connection record - #1704

Merged
giswqs merged 1 commit into
mainfrom
fix/redact-layer-connection
Aug 4, 2026
Merged

fix: redact credentials from a layer's connection record#1704
giswqs merged 1 commit into
mainfrom
fix/redact-layer-connection

Conversation

@giswqs

@giswqs giswqs commented Aug 4, 2026

Copy link
Copy Markdown
Member

Follow-up to #1702, closing the last gap the review raised there (that comment landed after the PR was merged).

The gap

redactProjectCredentials sweeps each layer's source, metadata, and sourcePath, but layer.connection passes through untouched. connection.lastError is free-form text taken from a caught error, and a refresh path that words it as `Failed to fetch ${url}` — a common pattern — would carry the request's ?token=… straight through Share, HTML export, embed, and collaboration.

Today's built-in refresh paths (layer-refresh.ts) only ever store generic strings like "Request failed with status 403", so nothing leaks in practice. This closes the blind spot so the module's no-secret guarantee does not depend on how a future error message happens to be phrased.

Changes

  • packages/core/src/credentials.ts — sweep layer.connection through redactConfigurationValue alongside the other three fields.
  • python/src/geolibre/project.py — the same field in the Python mirror, which had the identical gap.
  • Tests on both sides assert the token is stripped while the rest of the connection record (interval, timestamps, onFailure) survives.

Verification

  • npm run test:frontend — 5056 passing (2 new)
  • python -m pytest in python/ — 175 passing (1 new)
  • pre-commit run --files <changed> — clean

Summary by CodeRabbit

  • Bug Fixes

    • Expanded credential redaction to sanitize sensitive information in layer connection details, including nested data and URLs.
    • Removed credentials from connection error messages while preserving non-sensitive connection information.
    • Improved redaction tracking for sanitized connection fields.
  • Tests

    • Added coverage confirming tokens are removed from serialized project data and connection errors.

The egress redaction pass added in #1702 sweeps each layer's `source`,
`metadata`, and `sourcePath`, but leaves `connection` untouched.
`connection.lastError` is free-form text taken from a caught error, and a
refresh path that words it as `Failed to fetch ${url}` would carry the
request's credential parameters straight through Share, HTML export,
embed, and collaboration.

Today's built-in refresh paths only ever store generic status strings, so
nothing leaks in practice — this closes the blind spot rather than a live
bug, so the "no-secret guarantee" does not depend on how a future error
message is phrased.

- packages/core/src/credentials.ts: sweep `layer.connection` through
  `redactConfigurationValue` alongside the other three fields.
- python/src/geolibre/project.py: the same field in the Python mirror.
- Tests on both sides assert the token is stripped while the rest of the
  connection record (interval, timestamps) survives.
Copilot AI lite review requested due to automatic review settings August 4, 2026 21:40
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d1ac6628-b7c0-4d3d-be33-accf98dc04dc

📥 Commits

Reviewing files that changed from the base of the PR and between 43ae1b4 and 8a45962.

📒 Files selected for processing (4)
  • packages/core/src/credentials.ts
  • python/src/geolibre/project.py
  • python/tests/test_scripting.py
  • tests/project-credentials.test.ts

📝 Walkthrough

Walkthrough

Credential redaction now includes each layer’s connection object. TypeScript and Python implementations sanitize nested values and connection errors while preserving non-sensitive fields. Regression tests verify token removal and redaction path tracking.

Changes

Layer connection credential redaction

Layer / File(s) Summary
Extend layer redaction
packages/core/src/credentials.ts, python/src/geolibre/project.py
Layer connection data now passes through recursive credential redaction. Connection errors and nested credential-bearing values are sanitized.
Validate connection sanitization
tests/project-credentials.test.ts, python/tests/test_scripting.py
Regression tests verify token removal, preserved connection metadata, and recorded redaction paths.

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

Possibly related PRs

  • opengeos/GeoLibre#1702: Both changes extend credential redaction in the TypeScript and Python implementations.

Suggested reviewers: copilot

Poem

I hop through layers, neat and bright,
Scrubbing tokens out of sight.
Errors lose their secret trail,
Safe fields stay within the tale.
Redacted paths now mark the way.

🚥 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 and concisely describes the main change: credential redaction for a layer's connection record.
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.
✨ 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 fix/redact-layer-connection

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


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.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

This confirms the test is well-formed and mirrors the TS test correctly.

Given the small, well-scoped nature of this PR and the thorough verification, I don't have any inline comments to post — I did not find bugs, security issues, or CLAUDE.md violations. The one thing worth noting (very low severity, not worth an inline comment) is that the PR description claims the tests assert onFailure and lastSyncedAt survive redaction, but neither test actually asserts those two fields — only interval is checked alongside lastError. This is a documentation/test-coverage nit, not a functional bug, since manual trace-through confirms those fields are correctly preserved by the implementation.

Code review

Bugs: None found. Traced redactConfigurationValue/_redact_config against the new connection sweep: none of LayerConnection's field names (layerId, interval, lastSyncedAt, lastError, onFailure) collide with the credential-field registry, so only lastError gets its URL-embedded token stripped while the rest of the record passes through untouched — matches the intended behavior. Confidence: high.

Security: This closes a real gap — connection.lastError previously bypassed redactProjectCredentials/redact_credentials entirely, so a future refresh path that embeds the request URL (with query-string credentials) in a caught-error message would have leaked it through Share, HTML export, embed, and collaboration. Confirmed no other export path bypasses the shared redaction function, so the fix is centralized correctly. Confidence: high.

Performance: No concerns — the added sweep is O(1) extra field per layer, using the existing recursive redactor. Confidence: high.

Quality: TS and Python implementations are kept symmetric, consistent with the existing sourcePath conditional-spread pattern, and both are covered by a new test on each side. Minor nit (not inline-worthy): the PR description says tests assert onFailure and timestamps survive, but only interval is asserted alongside lastError in both the TS and Python tests — the other fields are untested even though manual analysis confirms they're preserved correctly. Confidence: medium.

CLAUDE.md: No violations — this doesn't touch any of the mirrored-constant modules the guidelines call out (Whitebox catalog, PMTiles zoom caps, remote file size limits, etc.), and no lockfile or CSP changes are involved.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🔍 Cloudflare PR preview

Item Value
Site https://abd2500b.geolibre-preview.pages.dev
Demo app https://abd2500b.geolibre-preview.pages.dev/demo/
Commit 8a45962

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Closes a remaining credential-redaction gap by ensuring each layer’s persisted connection record (notably connection.lastError, which can contain request URLs) is swept through the same redaction logic as other layer configuration, preventing secrets from leaking via Share/HTML export/embed/collaboration and Python serialization.

Changes:

  • Redact layer.connection via redactConfigurationValue in @geolibre/core’s redactProjectCredentials.
  • Mirror the same sweep in the Python project redaction helper.
  • Add JS + Python tests asserting query-token removal while preserving non-sensitive connection fields.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/core/src/credentials.ts Adds layer.connection to the redaction sweep using the existing configuration redactor.
tests/project-credentials.test.ts Adds a regression test ensuring connection.lastError cannot carry credential query params out of the project.
python/src/geolibre/project.py Extends Python redaction to sweep layer["connection"] alongside existing layer fields.
python/tests/test_scripting.py Adds a Python regression test validating redaction of secrets from connection.lastError.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +409 to +412
"interval": 300,
"lastSyncedAt": "2026-01-01T00:00:00.000Z",
"lastError": "Failed to fetch https://example.com/tiles?token=py-connection-secret",
"onFailure": "keep-last",
Comment on lines +151 to 157
# `connection.lastError` is free-form text taken from a caught
# error, which a future refresh path could easily build from the
# request URL. Sweeping it costs nothing and keeps the no-secret
# guarantee from depending on how an error message is worded.
for field in ("source", "metadata", "sourcePath", "connection"):
if field in layer:
layer[field] = _redact_config(layer[field])
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

🔍 GitHub Pages PR preview

Item Value
Site Deploy failed. See the job log.
Demo app Unavailable
Commit 8a45962

@giswqs
giswqs merged commit 8a7d3dd into main Aug 4, 2026
19 checks passed
@giswqs
giswqs deleted the fix/redact-layer-connection branch August 4, 2026 22:49
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.

2 participants