This page is for security reviewers who need to understand what is running inside psLens before approving its deployment. It covers four questions:
- What code is actually running?
- Can we audit it?
- How is it built and shipped?
- How are vulnerabilities found, disclosed, and fixed?
If you’re looking for the higher-level read-only / whitelist story, start with Security & Trust and come back here for the detail.
1. What’s Inside the Image
psLens is a single Go binary plus an embedded NATS server, packaged as a multi-stage Docker image distributed from ghcr.io/cedarhillsgroup/pslens. There is no separate database, message broker, or external worker process; one container is the whole application.
Runtime stack
| Component | Purpose |
|---|---|
| Go 1.26+ | Application language; binary statically linked |
gorilla/mux | HTTP routing |
a-h/templ | Server-rendered HTML templates |
Embedded NATS (nats-server/v2) | In-process key-value store for sessions, alerts, report output |
data-star (datastar.dev) | Hypermedia / SSE for interactive UI; no SPA framework |
| Goldmark | Markdown rendering for report output |
Standard library crypto/aes, crypto/tls | Encryption at rest and in transit |
There is no embedded browser, no third-party telemetry SDK, no analytics tracker. The full dependency list is go.mod in the source tree.
Base image
The runtime stage is debian:bookworm-slim with ca-certificates. No shell access is required for normal operation; psLens runs as PID 1.
2. Source Availability and Review
psLens is closed-source. The source tree is not published publicly.
For customers who need to review the code: Cedar Hills Group offers a read-only source review under NDA as part of the procurement process. Mechanics (on-site, screen-share, time-boxed access) are agreed during contracting. Reach out via the contact page to arrange.
This is the same model used by most enterprise PeopleSoft tooling: the binary is yours to run, the source is reviewable under contract, redistribution is not granted.
3. Build and Distribution
Build pipeline
| Stage | Where it runs | What it produces |
|---|---|---|
| Source commit | Cedar Hills Group internal repo | Tagged release commit (semver) |
| CI build | GitHub Actions, GitHub-hosted runners | Multi-arch Docker image |
| Publish | GitHub Container Registry (GHCR) | Private package, tagged vMAJOR.MINOR.PATCH, vMAJOR.MINOR, latest, git SHA |
The release pipeline injects the version, commit SHA, and ISO-8601 build timestamp into the binary at compile time via Go ldflags. You can read them back from any running instance via /healthz and the startup banner in container logs. Useful for confirming exactly which build a customer is running.
What we do today
- Traceable builds. Every image embeds the git SHA and build timestamp in its label and binary; you can map any running container back to the exact source commit that produced it.
- Pinned tag flavors. Production customers pin to
vMAJOR.MINOR(or exactvMAJOR.MINOR.PATCH) so adocker compose pullnever surprises them with a major-version change. See Deployment Options for the tag flavors and recommended pinning. - Private package distribution. GHCR access is gated by per-customer read-only fine-grained personal access tokens.
What we don’t do yet (roadmap)
- Image signing with cosign. Planned. Once landed, every published tag will carry a sigstore-verifiable signature and you’ll be able to verify provenance with
cosign verify. - SLSA build provenance attestation. Planned alongside cosign.
4. Dependency Management
Today
go.modis the single source of truth; all dependencies are pinned by version and content hash (go.sum).- Dependency updates are reviewed by hand at each release. We don’t accept untrusted PRs against
go.mod. - The dependency footprint is intentionally narrow (see the table above); Go standard library does most of the work.
Gaps and roadmap
- No automated SCA in CI today.
govulncheck, Dependabot, Renovate, CodeQL, andgosecare not currently wired into the release pipeline. - Roadmap: add
govulncheckto the release workflow as a blocking step, and enable Dependabot security updates on the source repo.
If your security policy requires SBOM artifacts as part of vendor onboarding, ask on the demo call. We can generate a CycloneDX or SPDX SBOM from a tagged build on request.
5. Vulnerability Disclosure and Patching
Reporting a vulnerability
Email security@cedarhillsgroup.com. Please include:
- Affected version (the git SHA from
/healthzis most precise) - Reproduction steps or proof-of-concept
- Your assessment of severity (CVSS or descriptive)
We commit to:
- Acknowledgement within 1 business day of receipt.
- Coordinated disclosure. We will agree a disclosure window with the reporter before publishing details.
- Crediting researchers in the release notes unless they prefer otherwise.
Patch SLA
Specific patch targets (business days for Critical, High, Medium) are disclosed during contracting.
When a fix ships, it goes out as a patch release in the same vMAJOR.MINOR stream you’re already pinned to. docker compose pull && docker compose up -d picks it up. Critical fixes are also announced by email to deployment contacts.
Subscribing to release notes
Release notes are published as GitHub Releases on the source repo. Deployment contacts are notified by email for any release with a security note.
6. What Reviewers Usually Ask
“Is the binary statically linked?” Yes. Go produces a static binary; no system library version drift.
“Does it phone home?” No. There is no outbound connection from a running psLens instance other than (a) to your SWS endpoint and (b) to your SMTP server if you’ve enabled magic-link auth. No telemetry, no update checks, no license-server callbacks.
“What user does it run as inside the container?” Confirm the current default with us on the demo call. Recommendation for self-hosters regardless: run with --user 1000:1000 and a read-only root filesystem; only /data needs to be writable.
“How big is the attack surface?” One HTTP listener (default port 8080 or whatever you configure), serving HTML and Server-Sent Events. No raw socket listeners, no UDP, no message-queue ingress, no plugin loader.
Related
- Authentication & Access. How the HTTP listener authenticates users.
- Data Handling & Logging. What’s stored, how it’s encrypted, what’s logged.
- Deployment & Operations. Backup, upgrade, sizing.
- Compliance & Vendor. SOC 2 posture, sub-processors, DPA.