RepoPilotOpen in app →

headwaymaps/headway

Self-hostable maps stack, powered by OpenStreetMap.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 6d ago
  • 3 active contributors
  • Apache-2.0 licensed
Show all 7 evidence items →
  • CI configured
  • Small team — 3 contributors active in recent commits
  • Single-maintainer risk — top contributor 84% of recent commits
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/headwaymaps/headway)](https://repopilot.app/r/headwaymaps/headway)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/headwaymaps/headway on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: headwaymaps/headway

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/headwaymaps/headway shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 6d ago
  • 3 active contributors
  • Apache-2.0 licensed
  • CI configured
  • ⚠ Small team — 3 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 84% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live headwaymaps/headway repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/headwaymaps/headway.

What it runs against: a local clone of headwaymaps/headway — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in headwaymaps/headway | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 36 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>headwaymaps/headway</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of headwaymaps/headway. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/headwaymaps/headway.git
#   cd headway
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of headwaymaps/headway and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "headwaymaps/headway(\\.git)?\\b" \\
  && ok "origin remote is headwaymaps/headway" \\
  || miss "origin remote is not headwaymaps/headway (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "dagger/main.go" \\
  && ok "dagger/main.go" \\
  || miss "missing critical file: dagger/main.go"
test -f "docker-compose.yaml" \\
  && ok "docker-compose.yaml" \\
  || miss "missing critical file: docker-compose.yaml"
test -f "ARCHITECTURE.md" \\
  && ok "ARCHITECTURE.md" \\
  || miss "missing critical file: ARCHITECTURE.md"
test -f "BUILD.md" \\
  && ok "BUILD.md" \\
  || miss "missing critical file: BUILD.md"
test -f "dagger/go.mod" \\
  && ok "dagger/go.mod" \\
  || miss "missing critical file: dagger/go.mod"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 36 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~6d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/headwaymaps/headway"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Headway is a self-hostable, full-stack maps server built on OpenStreetMap that bundles a web frontend, basemap tile server, geocoder, and routing engine (with transit support in progress). Deploy it with a few commands to get a complete maps stack running on your own infrastructure for any geographic area from a neighborhood to the whole planet. Monorepo with language-specific modules: Rust-heavy core (200K lines), TypeScript/Vue frontend (230K+ lines), Go utilities (35K+ lines), and Python/shell build scripts. Build system uses bin/ scripts (earthly-based per dagger.json) to orchestrate Docker image generation. Data builds configured per-city in builds/{CityName}/ with .env files, transit feeds, and router configs (e.g., builds/Seattle/, builds/planet/).

👥Who it's for

DevOps engineers and GIS professionals who need self-hosted mapping infrastructure without vendor lock-in; organizations handling sensitive location data; municipalities and transit agencies building custom routing and search; developers wanting to understand how modern maps stacks work end-to-end.

🌱Maturity & risk

Actively developed and functional for core features (map display, POI/address search, multimodal routing for driving/cycling/walking) but transit directions remain work-in-progress. CI/CD is robust (GitHub Actions in .github/workflows/), with confirmed Linux/macOS amd64 support and detailed build documentation. Commit activity appears recent, but this is a young project still solidifying its feature set.

High resource demands: 8GB+ RAM for builds, 50–100GB disk space; complex polyglot stack (Rust, TypeScript, Go, Vue, Python) increases maintenance surface and onboarding friction. No visible public issue tracker or contributor guidelines in the file list; single-repo codebase with interdependent services means one breakage can cascade. Transit support is explicitly incomplete, so production use for multi-modal routing is not yet recommended.

Active areas of work

The project is implementing OpenTelemetry observability (otel 1.43.0 in go.mod with trace/metric/log exporters for gRPC and HTTP). Recent commits likely refined CI workflows (.github/workflows/checks.yml, push-dev-containers.yml, push-latest-containers.yml). Transit direction support is actively being added (evidence: bin/build-transit, transit configs in builds/, OTP router configs).

🚀Get running

Clone the repo, then follow BUILD.md: likely ./bin/build to compile all services with the Earthly-based build system. Ensure 8GB+ RAM and ~100GB free disk. Use bin/start-services and bin/wait-for-services to bring up the stack (Docker Compose via bin/docker-compose). Reference builds/Seattle/.env or builds/planet/.env for example configuration.

Daily commands: See BUILD.md and bin/ scripts: ./bin/build to compile (requires Earthly/Dagger), then ./bin/start-services to launch via Docker Compose, then ./bin/wait-for-services to verify readiness. Environment configuration via .env files (example: builds/Seattle/.env). For development iteration, individual services likely support hot-reload but exact commands depend on service type—check service-specific Dockerfiles.

🗺️Map of the codebase

  • dagger/main.go — Entry point for the Dagger CI/CD pipeline that orchestrates the entire build process for all components
  • docker-compose.yaml — Core service orchestration file defining all microservices (Pelias, Valhalla, TileServer, OpenTripPlanner, etc.) and their networking
  • ARCHITECTURE.md — High-level system design document explaining component interactions and data flow across the stack
  • BUILD.md — Build process documentation and instructions that every contributor must follow to understand deployment workflows
  • dagger/go.mod — Go module dependencies including OpenTelemetry, GraphQL, and core libraries that define the project's tech foundation
  • k8s/_template — Kubernetes deployment templates used to generate production configs for all services across different regions

🛠️How to make changes

Add Support for a New Geographic Region

  1. Create a new build directory with region name under builds/ (e.g., builds/MyCity/) (builds/MyCity/.env)
  2. Add OSM extract download URL and region bounds to the .env file (builds/MyCity/.env)
  3. If transit routing needed, create GTFS feed CSV referencing transit authority feeds (builds/MyCity/transit/gtfs-feeds/MyCity.gtfs_feeds.csv)
  4. Create OpenTripPlanner router configuration JSON with region-specific settings (builds/MyCity/transit/MyCity-router-config.json)
  5. Generate Kubernetes manifests by running bin/k8s-generate and update k8s/configs/ with region-specific overrides (k8s/_template/opentripplanner-AREA-deployment.yaml.tpl)

Customize the Basemap Styling

  1. TileServer GL reads style configs from mounted volumes defined in docker-compose.yaml (docker-compose.yaml)
  2. Create custom Mapbox-format style JSON and mount via volume in docker-compose or K8s PVC (k8s/_template/tileserver-deployment.yaml.tpl)
  3. Update service environment variables to point to new style file path (builds/planet/.env)
  4. Rebuild containers and redeploy using bin/build-images and bin/docker-compose up (bin/build-images)

Add a New Microservice to the Stack

  1. Create Dagger pipeline stage in dagger/main.go to build and push the service container (dagger/main.go)
  2. Create Docker Compose service definition in docker-compose.yaml with environment, volumes, and networking (docker-compose.yaml)
  3. Create Kubernetes Deployment and Service templates under k8s/_template/ (k8s/_template/newservice-deployment.yaml.tpl)
  4. Update travelmux or API gateway config to route requests to the new service endpoint (k8s/_template/travelmux-deployment.yaml.tpl)
  5. Regenerate Kubernetes configs using bin/k8s-regenerate-all (bin/k8s-regenerate-all)

Deploy to Kubernetes with a New Configuration

  1. Copy and customize an existing config directory (e.g., from k8s/configs/planet-dev/) to k8s/configs/my-deployment/ (k8s/configs/planet-dev)
  2. Edit deployment-config.yaml to set region, data sources, resource limits, and service replicas (k8s/configs/planet-dev/deployment-config.yaml)
  3. Regenerate all service manifests with bin/k8s-regenerate-all to pick up custom values (bin/k8s-regenerate-all)
  4. Apply manifests to cluster: kubectl apply -f k8s/configs/my-deployment/ (k8s/configs/planet-dev)
  5. Monitor startup with bin/wait-for-services to ensure all services are healthy (bin/wait-for-services)

🔧Why these technologies

  • OpenStreetMap (OSM) + Pelias — Decouples from proprietary map data providers; Pelias enables fast geocoding over any OSM extract
  • Valhalla + OpenTripPlanner — Valhalla handles car/bike/pedestrian routing; OpenTripPlanner adds multi-modal transit with GTFS integration
  • TileServer GL — Lightweight, self-hosted basemap tiling engine supporting Mapbox-format styles without external dependencies
  • Dagger + Docker Compose + Kubernetes — Provides flexible deployment from single-machine (Compose) to planet-scale (K8s) without rewriting configs
  • OpenTelemetry — Observability-first architecture enabling distributed tracing, metrics, and logging across heterogeneous services

⚖️Trade-offs already made

  • Single Dagger pipeline generating Docker/K8s configs vs. separate build systems

    • Why: Reduces configuration drift and maintenance burden across deployment targets
    • Consequence: Go-based Dagger learning curve for non-Go developers; template duplication in k8s/_template/
  • Multi-region OpenTripPlanner instances vs. single federated instance

    • Why: Each region can operate independently with its own GTFS data and configuration; simpler failure isolation
    • Consequence: Increased operational overhead; inter-region transfers require coordination; no true global transit optimization
  • Stateless microservices with volume-mounted data vs. managed databases

    • Why: Simplifies self-hosting and data sovereignty; avoids lock-in to cloud providers
    • Consequence: Operator must manage OSM/GTFS data pipelines; restart times proportional to data volume; harder to scale horizontally
  • Template-based Kubernetes generation vs. Helm charts or Kustomize

    • Why: Keeps configuration logic centralized in Dagger/shell scripts; easier to audit what deploys
    • Consequence: undefined

🪤Traps & gotchas

Environment setup: bin/_source-env.sh and bin/_headway_version.sh must be sourced before build scripts; version pinning is critical. Resource starvation: Builds fail silently with <8GB RAM; no automatic memory detection in visible scripts. Earthly/Dagger dependency: All builds route through dagger.json and Earthly container system—Docker daemon must be running and healthy. Service startup order: bin/start-services and bin/wait-for-services imply service dependencies (e.g., tiles before search); incorrect startup order causes cryptic connection errors. Data freshness: OSM extracts and GTFS feeds hardcoded in builds/{city}/ can become stale; no auto-update mechanism visible. Multi-language polyglot issues: Rust, Go, TypeScript, Python, and Shell all in critical path means version mismatches (e.g., Rust toolchain, Node version, Python 3.x vs 2.x) can break builds with opaque errors.

🏗️Architecture

💡Concepts to learn

  • Vector tiles (MVT/PBF format) — Headway's basemap server likely generates Mapbox Vector Tiles; understanding tile coordinate systems, z/x/y indexing, and GeoJSON→PBF encoding is essential for modifying or debugging map rendering and storage.
  • Geospatial indexing (R-tree, quad-tree) — The Rust core uses spatial indexes for fast POI/address search and intersection queries; understanding how bounding boxes and Morton codes accelerate geographic queries is key to optimizing geocoding.
  • Graph routing algorithms (Dijkstra, A*, Contraction Hierarchies) — OpenTripPlanner's routing core uses CH for speed; Headway's custom routing logic likely implements similar algorithms for walking/cycling/driving modes. Understanding trade-offs (precomputation vs. query time) is vital for transit feature completion.
  • GTFS (General Transit Feed Specification) — Transit support ingests GTFS CSV feeds in builds/*/transit/gtfs-feeds/; parsing stop times, schedules, and stop locations is the data backbone for multi-modal routing.
  • OpenTelemetry distributed tracing — go.mod lists otel 1.43.0 for observability; Headway aims to emit traces across Rust/Go/TS services for debugging latency and failures in the microservices architecture.
  • Reproducible container builds — Earthly/Dagger orchestrates multi-stage builds; understanding cache layers, pin-able dependencies, and deterministic timestamps is crucial for reliable city deployments and preventing silent data drift.
  • OSM PBF (Protocol Buffer Format) parsing — Headway ingests OpenStreetMap extracts in PBF format; parsing OSM ways, nodes, and tags efficiently in Rust is foundational for importing road networks and POIs.
  • openstreetmap/operations — Upstream OSM infrastructure; Headway consumes OSM extracts and would benefit from tracking OSM's data quality and tile schema changes.
  • opentripplanner/OpenTripPlanner — Transit routing engine integrated via OTP configs in builds/*/transit/; understanding OTP's router-config.json schema and GTFS handling is necessary for transit feature completion.
  • graphhopper/graphhopper — Alternative open-source routing engine; Headway uses OTP, but GH is a design reference for embedded multimodal routing without external services.
  • maplibre/maplibre-gl-js — Likely vector tile frontend renderer; Headway's Vue frontend probably uses MapLibre or similar GL.js for interactive map display.
  • OSMBoundaries/OSMBoundaries — Administrative boundary data source; relevant for geocoding reverse-lookups and city boundary definition in Headway's search index.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for build configurations across multiple cities

The repo contains multiple build configurations (Bogota, Seattle, planet) in builds/ with different .env and transit configs, but there's no visible test suite validating that these builds work correctly. A new contributor could create integration tests that verify each build's configuration is valid, transit feeds are accessible, and the docker-compose files render correctly with their respective .env files.

  • [ ] Create tests/integration/builds_test.go to validate each builds/*/.env file is properly formatted
  • [ ] Add validation that gtfs-feeds CSV files in builds/*/transit/gtfs-feeds/ are parseable
  • [ ] Create a test that verifies docker-compose.yaml and docker-compose-with-transit.yaml can be rendered with sample build configs
  • [ ] Add test to validate router-config.json files in builds/*/transit/ have required OTP fields
  • [ ] Integrate tests into .github/workflows/checks.yml

Add OpenTelemetry instrumentation verification tests in dagger/

The go.mod shows heavy OpenTelemetry dependencies (trace, metrics, logs exporters for OTLP), but dagger/main.go lacks visible tests validating that OTel instrumentation is properly configured. A contributor could add tests ensuring the instrumentation is initialized and exporters are reachable, helping catch telemetry pipeline breaks early.

  • [ ] Create dagger/otel_test.go with unit tests for OTel exporter initialization
  • [ ] Add test validating OTLP gRPC endpoint connectivity (uses testcontainers or mock)
  • [ ] Create test for metric and trace exporter configuration with various env var combinations
  • [ ] Add test validating that replace directives in go.mod (otlploggrpc, otlploghttp) don't cause import conflicts
  • [ ] Document OTel setup requirements in a new OTEL_INSTRUMENTATION.md file

Create validation script and tests for Kubernetes template rendering

The k8s/_template/ directory contains 10+ Jinja-style .tpl files for Kubernetes deployments, but there's no visible validation that these templates render correctly with sample values or that the output YAML is valid Kubernetes manifests. A contributor could add template validation to catch configuration drift.

  • [ ] Create tests/k8s/template_validation_test.go to test k8s/_template/ rendering
  • [ ] Add validation that rendered YAML passes kubectl --dry-run=client validation
  • [ ] Create test fixtures in tests/k8s/fixtures/ with sample deployment-config values
  • [ ] Test that all required variables (AREA, IMAGE_TAG, etc.) are properly substituted in templates
  • [ ] Add bin/validate-k8s-templates.sh script and integrate into .github/workflows/checks.yml

🌿Good first issues

  • Add explicit version constraints documentation: Create a VERSIONS.md file listing pinned Rust (MSRV), Go (1.25.0 visible in dagger.json), Node.js, and Python 3.x versions with pre-commit hooks in bin/pre-commit to validate them. Current repo has no centralized version declaration.
  • Extract and document OpenTelemetry instrumentation: The go.mod shows comprehensive otel 1.43.0 setup but no visible service code uses it. Write a guide in docs/INSTRUMENTATION.md with concrete examples for adding trace spans to Rust tile server and Go data pipelines, then submit one integration PR.
  • Build reproducibility tests: Add a GitHub Actions workflow to bin/verify-deterministic-build.sh that rebuilds Seattle build twice and compares artifact checksums. Catch non-deterministic tile/index generation early. Would catch silent data corruption from tool version mismatches.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • b5082cd — Merge pull request #411 from headwaymaps/mkirk/martin-tileserver (michaelkirk)
  • a1a6579 — remove unused HEADWAY_AREA in k8s configs (michaelkirk)
  • 3cc211f — Switch to martin (michaelkirk)
  • 951c4b9 — Merge pull request #410 from headwaymaps/mkirk/update-maplibre-v5 (michaelkirk)
  • 5086bd6 — build-images filters by image name (michaelkirk)
  • 2661297 — helper script for docker compose commands (michaelkirk)
  • b074f1d — Add some detail to ARCHITECTURE.md (michaelkirk)
  • 9d8dc23 — [www] update maplibre (michaelkirk)
  • 6f3909a — Merge pull request #409 from headwaymaps/mkirk/update-deps-2026-04 (michaelkirk)
  • b82bb7e — fix tileserver, apparently the binary was renamed (michaelkirk)

🔒Security observations

  • High · Outdated Go Dependencies with Known Vulnerabilities — dagger/go.mod. The go.mod file specifies golang.org/x/net v0.53.0 and golang.org/x/sys v0.43.0, which are significantly outdated (released in early 2024). These versions likely contain known CVEs. Additionally, google.golang.org/protobuf v1.36.11 and google.golang.org/grpc v1.80.0 should be verified against current security advisories. Fix: Update all dependencies to their latest stable versions. Run 'go get -u ./...' and 'go mod tidy'. Verify no CVEs exist in updated versions using 'go list -json -m all | nancy sleuth' or similar tools.
  • High · Broken Dependency Replacement — dagger/go.mod (line with otlploghttp replacement). The go.mod file contains an incomplete replace directive: 'replace go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp =>' with no replacement target specified. This is a syntax error that could cause build failures or unexpected behavior. Fix: Complete the replace directive with a valid version or remove it if not needed. The pattern should be 'replace <original> => <replacement>' with a valid target module and version.
  • High · Environment Files with Potential Secrets — builds/Bogota/.env, builds/Seattle/.env, builds/planet/.env. Multiple .env files exist in the repository (builds/Bogota/.env, builds/Seattle/.env, builds/planet/.env) and are tracked in version control. These files commonly contain sensitive configuration like API keys, database passwords, and credentials that should never be committed. Fix: Remove .env files from git history using 'git rm --cached' and add them to .gitignore. Use .env.example files instead with placeholder values. Implement secret management via environment variables, HashiCorp Vault, or Kubernetes Secrets for production deployments.
  • High · Docker Image Pinning Issues — docker-compose.yaml (tileserver-init and tileserver services). The docker-compose.yaml uses 'latest' tags for critical services (ghcr.io/headwaymaps/tileserver-init:latest, ghcr.io/headwaymaps/tileserver:latest). The 'latest' tag is mutable and can change unexpectedly, introducing security risks and reproducibility issues. Fix: Pin all Docker images to specific immutable SHA256 digests or version tags (e.g., 'ghcr.io/headwaymaps/tileserver:v1.2.3' or 'ghcr.io/headwaymaps/tileserver:sha256:...'). This ensures consistent, reproducible deployments.
  • Medium · Incomplete Docker Compose Configuration — docker-compose.yaml (travelmux-init service). The docker-compose.yaml file appears truncated with the 'travelmux-init' service definition incomplete ('image:' with no value). This suggests either a broken configuration or incomplete file copy, which could lead to service startup failures. Fix: Complete the docker-compose.yaml configuration with proper image references and all required service definitions. Validate with 'docker-compose config' before deployment.
  • Medium · World-Readable Data Volumes — docker-compose.yaml (tileserver-init and tileserver volumes). The docker-compose.yaml mounts volumes with ':ro' and ':rw' permissions without explicit user/owner constraints. The tileserver_data volume is shared between multiple services with read-write access, potentially allowing privilege escalation or data corruption. Fix: Define explicit user ownership for volumes (e.g., 'user: 1000:1000'). Implement least-privilege access patterns. Use Docker volume drivers with encryption. Consider implementing pod security policies in Kubernetes deployments.
  • Medium · No Network Segmentation — docker-compose.yaml (networks configuration). Services are exposed on a shared 'tileserver_frontend' network without explicit network segmentation or firewall rules. This increases the attack surface by allowing lateral movement between services. Fix: Implement network policies to restrict inter-service communication. Create separate networks for frontend, backend, and data services. Use network

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · headwaymaps/headway — RepoPilot