Commit Graph
4 Commits
Author SHA1 Message Date
jcoffey-dev 13cf9a30cb Rebrand: Sentry -> Cairn OBS
Full rebrand across cosmetic branding, code identifiers, and
infrastructure/data-plane naming, using the supplied Cairn OBS logo
package. Cosmetic: favicon/logo swap (also closes a stale license-audit
finding -- the old favicon was SvelteKit's unreplaced scaffold logo),
new centered welcome landing page, larger/legible sidebar logo, page
titles, CLAUDE.md/README/docs prose.

Code identifiers: Go module path github.com/sentry/sentry ->
github.com/cairnobs/cairnobs across all 13 modules and ~91 files (protoc
regenerated); Rust crates sentry-agent/sentry-parser/sentry-search ->
cairnobs-*; CLI sentryctl -> cairnobsctl; Terraform provider fully
renamed (sentry_dashboard etc. -> cairnobs_dashboard, provider type,
env vars); every session/auth cookie name; agent config paths and
Windows service identity.

Deliberately preserved: the gRPC wire protocol's protobuf packages
(sentry.logs.v1, sentry.agent.v1) and their Go import directory
(proto/sentry/...) -- renaming the wire-level package would break every
currently-deployed agent binary (confirmed two real hosts, including
mail.inbuxa.com, are actively streaming through this exact contract)
until rebuilt and redeployed in lockstep with an ingest cutover. Only
the Go module path wrapping the generated code changes.

Infrastructure: every docker-compose container name (root and three
component-level compose files); the Helm chart (directory, Chart.yaml,
named-template helpers, all templates, values.yaml image repos);
Kubernetes Operator (CRD group sentry.io -> cairnobs.io, both CRD YAML
files, Go identifiers, RBAC markers); the coupled enterprise/tenantcrd
package. Caught and fixed real path-coupling bugs along the way: the
Helm chart's search/ingest volume mounts and the dev-only-credential
detection constant vs. docker-compose.yml's literal values had to move
together or a security warning would have silently stopped firing.

Data plane: Postgres database sentry_metadata -> cairnobs_metadata and
role sentry -> cairnobs; ClickHouse database sentry -> cairnobs; Kafka
topic sentry.logs.raw -> cairnobs.logs.raw and its consumer groups.
Source-level defaults, docker-compose.yml, and every migrate.sh/
provision script default updated together; already-applied migration
files left untouched per this repo's immutable-migration convention.

Verified at every layer: all 13 Go modules build/vet/test clean, both
Rust workspaces (agent, search) build/clippy/test clean, npm run check/
build clean, docker compose config validates on all four compose files.
Live-verified against a real docker stack multiple times through this
work, including a final fresh-volume run confirming the actual renamed
Postgres database/role, ClickHouse database, and Kafka topic all work
end to end with a real login and query, zero console errors.
2026-08-21 20:53:32 -07:00
jcoffey-dev 653e4efa76 Enforce the full user-management RBAC matrix, add self-service password change
api/localauth now enforces every rule of the requested matrix, each
checked inside the handler beyond RegisterRoutes' floor:
  - At least one owner must always exist -- handleDeleteUser and
    handleSetRole both refuse an operation that would leave zero
    owners (wouldRemoveLastOwner, backed by new store method
    CountUsersWithRole), whether the caller is admin or owner.
  - Owner can create/delete any role, including another owner (subject
    to the above). Admin can only create/delete viewer or editor --
    GET/POST /auth/users and DELETE .../{id} moved from RoleOwner to
    RoleAdmin floor, with an inner check narrowing what an admin
    caller specifically may target.
  - Only a user can change their own password -- new POST
    /auth/password (RoleViewer floor, i.e. every role) requires the
    caller's current password (verified via new store method
    GetPasswordHashByID) and is now the only path to changing your
    own, including for an owner. The existing admin-reset endpoint
    (POST /auth/users/{id}/reset-password, also moved to RoleAdmin
    floor) now refuses id == the caller's own ID, and refuses an
    owner target unless the caller is themselves an owner -- "admin
    can change any password except an owner's; owner can change any
    password, even another owner's."
  - Role reassignment (PUT .../{id}/role) stays owner-only, unchanged
    beyond the last-owner guard above.

New web/src/routes/account page (linked from NavSidebar next to "Log
out", visible to every local-auth role) is the self-service password
change UI. /users now mirrors the server's per-row restrictions
client-side (disabled role selects/delete/reset buttons with an
explanatory title, a restricted role list on the create form) so an
admin never sees an action that would just 403 -- the server remains
the actual authority.

Verified live against real Postgres and in the browser: the full
matrix via curl (owner creating a second owner, admin blocked from
creating/deleting/resetting admin or owner accounts, last-owner delete
and demote both blocked, admin resetting non-owner passwords,
self-target reset rejected, self-service change with wrong/right
current password), plus the actual /users page rendering correctly
restricted for an admin session and a full change-password round trip
through the real UI ending in a forced re-login with the new password.
2026-08-21 16:18:29 -07:00
jcoffey-dev 864e68253a Give local users their own manager: custom passwords and role reassignment
Move user management out of Settings into its own /users page (nav-gated
to owners), let an owner type a specific password on reset instead of
always generating a random one, and add role reassignment via a new
PUT /auth/users/{id}/role endpoint. Role changes revoke the target's
existing sessions, same as a password reset, so a demoted user can't
keep acting under a stale, higher-privileged session.
2026-08-21 14:23:52 -07:00
jcoffey-dev 4b5dae5879 Add local login, agent extra log paths, IPv4/IPv6 metrics; remediate security audit findings
This is a large squashed commit covering two batches of prior uncommitted
work plus a full security-audit remediation pass, kept together because
go.mod/go.sum and several shared files (main.go, handler.go) were touched
by both and splitting risked non-building intermediate commits.

Features (built earlier, previously uncommitted):
- Local username/password login for single-tenant deployments with no
  SSO configured (api/localauth, alerting/internal/sessioncheck,
  sentryctl users, web/src/routes/login, metadata migrations 0040/0041).
- Remotely-editable additional log file paths for agents, on top of
  their existing primary source (api/agents, agent/sentry-agent
  extra-file-path diffing, web agent config UI).
- IPv4/IPv6 addresses reported alongside other host system metrics.

Security audit remediation (this pass, all live-verified in production):
- Critical: block ClickHouse SSRF table functions (url/remote/file/s3/...)
  in the raw-SQL query escape hatch.
- High: deny sensitive paths and require Admin to add agent
  extra_file_paths (Editor could previously point an agent at /etc/shadow
  or an SSH key); alerting webhook targets now validate against
  internal/metadata/loopback addresses, both at creation and send time;
  alerting's session middleware now enforces an Editor+ floor on
  mutating requests instead of "any authenticated session"; bumped
  goxmldsig to close a SAML signature-verification bypass (GO-2026-4753).
- Medium: per-IP login rate limiting; security response headers
  (HSTS/CSP/nosniff/X-Frame-Options/Referrer-Policy/Permissions-Policy)
  on web/nginx.conf; a DevCredentialWarnings check in every Go service's
  config loader, logging loudly at startup if a deployment is still on
  docker-compose.yml's literal dev-only credentials; dependency bumps
  (golang.org/x/text, grpc, x/net, quick-xml, h2) across every affected
  Go module and both Rust crates, including a previously-uncovered x/net
  vulnerability in deploy/operator; a new security-scan.yml CI workflow
  running cargo-deny/govulncheck/npm-audit, mirroring the existing
  license-compliance.yml matrix shape.
- Low: removed sentryctl's plaintext --password flag (shell
  history/`ps` exposure) in favor of stdin and a --password-stdin flag
  for reset-password's optional specific-password path; a dummy bcrypt
  comparison closes a login response-time username-enumeration
  side-channel.
2026-08-18 23:53:20 -07:00