93f3cc44a2c92c72c2ab3ad34956309c6481a17e
9
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6a05e9ce5c |
Bump the go-minor-and-patch group across 4 directories with 2 updates
Bumps the go-minor-and-patch group with 1 update in the /alerting directory: [github.com/jackc/pgx/v5](https://github.com/jackc/pgx). Bumps the go-minor-and-patch group with 2 updates in the /api directory: [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) and [golang.org/x/crypto](https://github.com/golang/crypto). Bumps the go-minor-and-patch group with 1 update in the /enterprise directory: [github.com/jackc/pgx/v5](https://github.com/jackc/pgx). Bumps the go-minor-and-patch group with 1 update in the /ingest directory: [github.com/jackc/pgx/v5](https://github.com/jackc/pgx). Updates `github.com/jackc/pgx/v5` from 5.10.0 to 5.11.0 - [Release notes](https://github.com/jackc/pgx/releases) - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.10.0...v5.11.0) Updates `github.com/jackc/pgx/v5` from 5.10.0 to 5.11.0 - [Release notes](https://github.com/jackc/pgx/releases) - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.10.0...v5.11.0) Updates `golang.org/x/crypto` from 0.56.0 to 0.57.0 - [Commits](https://github.com/golang/crypto/compare/v0.56.0...v0.57.0) Updates `github.com/jackc/pgx/v5` from 5.10.0 to 5.11.0 - [Release notes](https://github.com/jackc/pgx/releases) - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.10.0...v5.11.0) Updates `github.com/jackc/pgx/v5` from 5.10.0 to 5.11.0 - [Release notes](https://github.com/jackc/pgx/releases) - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](https://github.com/jackc/pgx/compare/v5.10.0...v5.11.0) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/crypto dependency-version: 0.57.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch ... Signed-off-by: dependabot[bot] <[email protected]> |
||
|
|
82cfe1fa0a |
Bump the go-minor-and-patch group across 5 directories with 9 updates
Bumps the go-minor-and-patch group with 1 update in the /alerting directory: [golang.org/x/sync](https://github.com/golang/sync). Bumps the go-minor-and-patch group with 1 update in the /api directory: [golang.org/x/crypto](https://github.com/golang/crypto). Bumps the go-minor-and-patch group with 3 updates in the /deploy/operator directory: [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery), [k8s.io/client-go](https://github.com/kubernetes/client-go) and [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime). Bumps the go-minor-and-patch group with 6 updates in the /enterprise directory: | Package | From | To | | --- | --- | --- | | [golang.org/x/sync](https://github.com/golang/sync) | `0.22.0` | `0.23.0` | | [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.31.0` | `0.37.0` | | [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.31.0` | `0.37.0` | | [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) | `3.20.0` | `3.21.0` | | [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) | `4.1.4` | `4.1.5` | | [golang.org/x/oauth2](https://github.com/golang/oauth2) | `0.36.0` | `0.37.0` | Bumps the go-minor-and-patch group with 1 update in the /ingest directory: [golang.org/x/sync](https://github.com/golang/sync). Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/crypto` from 0.55.0 to 0.56.0 - [Commits](https://github.com/golang/crypto/compare/v0.55.0...v0.56.0) Updates `k8s.io/apimachinery` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.0...v0.37.0) Updates `k8s.io/client-go` from 0.31.0 to 0.37.0 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.31.0...v0.37.0) Updates `sigs.k8s.io/controller-runtime` from 0.19.3 to 0.25.0 - [Release notes](https://github.com/kubernetes-sigs/controller-runtime/releases) - [Changelog](https://github.com/kubernetes-sigs/controller-runtime/blob/main/RELEASE.md) - [Commits](https://github.com/kubernetes-sigs/controller-runtime/compare/v0.19.3...v0.25.0) Updates `k8s.io/api` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/api/compare/v0.31.0...v0.37.0) Updates `k8s.io/apimachinery` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.0...v0.37.0) Updates `k8s.io/client-go` from 0.31.0 to 0.37.0 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.31.0...v0.37.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `k8s.io/apimachinery` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.0...v0.37.0) Updates `k8s.io/client-go` from 0.31.0 to 0.37.0 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.31.0...v0.37.0) Updates `github.com/coreos/go-oidc/v3` from 3.20.0 to 3.21.0 - [Release notes](https://github.com/coreos/go-oidc/releases) - [Commits](https://github.com/coreos/go-oidc/compare/v3.20.0...v3.21.0) Updates `github.com/go-jose/go-jose/v4` from 4.1.4 to 4.1.5 - [Release notes](https://github.com/go-jose/go-jose/releases) - [Commits](https://github.com/go-jose/go-jose/compare/v4.1.4...v4.1.5) Updates `golang.org/x/oauth2` from 0.36.0 to 0.37.0 - [Commits](https://github.com/golang/oauth2/compare/v0.36.0...v0.37.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `k8s.io/api` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/api/compare/v0.31.0...v0.37.0) Updates `k8s.io/apimachinery` from 0.31.0 to 0.37.0 - [Commits](https://github.com/kubernetes/apimachinery/compare/v0.31.0...v0.37.0) Updates `k8s.io/client-go` from 0.31.0 to 0.37.0 - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.31.0...v0.37.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](https://github.com/golang/sync/compare/v0.22.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/crypto dependency-version: 0.56.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/apimachinery dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/client-go dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: sigs.k8s.io/controller-runtime dependency-version: 0.25.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/api dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/apimachinery dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/client-go dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/apimachinery dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/client-go dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: github.com/coreos/go-oidc/v3 dependency-version: 3.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: github.com/go-jose/go-jose/v4 dependency-version: 4.1.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-minor-and-patch - dependency-name: golang.org/x/oauth2 dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/api dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/apimachinery dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: k8s.io/client-go dependency-version: 0.37.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-minor-and-patch ... Signed-off-by: dependabot[bot] <[email protected]> |
||
|
|
b7f99b49f2 |
Take grpc to 1.83.2 across the nine modules that carry it
GHSA-2v4p-qf9q-27wj is a panic in gRPC-Go's xDS routing interceptor: a request arriving with neither `:authority` nor `Host` indexes an empty slice, the per-RPC goroutine does not recover, and the process dies. High, and nine alerts, because nine go.mod files pin the same version -- eight directly, terraform indirectly. Nothing here was reachable. The interceptor is installed by `xds.NewGRPCServer`, which this repo never calls: the one production server is `grpc.NewServer(grpc.Creds(...))` in ingest/internal/grpcserver and the only other is a plain one in a searchclient test. That is also why security-scan has been green throughout -- govulncheck reports on reachability and found nothing on 1.83.1, while Dependabot reports on version ranges and found nine. Both were right. Taken anyway: it is a patch release, and the next advisory in this dependency may well land somewhere we do reach. `go mod tidy` carried the indirect requirements grpc 1.83.2 asks for -- x/net, x/text, x/sys and friends. No CI job builds or tests Go here, so all nine modules were built locally and api, ingest and enterprise tested with -count=1, since a cached pass would not have exercised the new version. The dependabot.yml is the other half. There was no config, so nothing opened a PR against any of this. Go majors stay out of the group, being import path changes rather than bumps. |
||
|
|
200f801e2c |
Clear the Dependabot findings
Dependabot alerts were switched on for this repo today and reported 12 open findings. Ten are fixed here; the other two are addressed below. gRPC 1.83.0 -> 1.83.1, in all nine modules that require it. This is GHSA-vp52-pcj8-j9qc / CVE-2026-84304, heap memory exhaustion via HTTP/2 DATA frame fragmentation, affecting <= 1.83.0. It matters more than the version delta suggests: ingest/ is a gRPC listener deliberately exposed to the internet on :4317, so a remote OOM is reachable. mTLS narrows that to holders of a client certificate, which is why this was not an emergency, but the fix is one patch release away and there is no reason to carry it. golang.org/x/oauth2 0.21.0 -> 0.27.0 in deploy/operator, an indirect dependency (GHSA-6v2p-p543-phr9). enterprise/ was already past it at 0.36.0. npm cookie 0.6.0 -> 0.7.2, via an overrides entry rather than a dependency bump. @sveltejs/kit requires ^0.6.0 and still does at 2.70.3, the latest release, so there is no version of kit that resolves this on its own -- an override is the only route that does not involve waiting on upstream. Three incidental changes came out of `go mod tidy` and are not mine: genproto/googleapis/rpc moved forward as a transitive of the new grpc; pgx/v5 was reclassified from indirect to direct in enterprise/, which is simply correct, since audit.go and cmd/enterprise-auth import it; and the proto replace directive shuffled between require blocks at the same version. The twelfth finding, lru (GHSA-rhfx-m35p-ff5j), is not fixed and is not fixable here -- see the note in the pull request. It is CVSS 0, a Stacked Borrows soundness issue in IterMut, and reaching a patched version means tantivy 0.22 -> 0.26, which is a search engine migration rather than a dependency bump. Verified: all ten Go modules build, 40 test packages pass, the web app builds and svelte-check reports 0 errors across 288 files. |
||
|
|
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. |
||
|
|
1de77b969f |
Build per-tenant ClickHouse write-routing for ingest (Tantivy still deferred)
ingest tags every record with a tenant_id Kafka header (built previously), but nothing consumed it to actually route the write. This closes that for ClickHouse: enterprise/cmd/enterprise-ingest (a second binary, mirroring enterprise-api) reuses ingest/consumer's own flush loop unchanged, with enterprise/internal/chwriter.Registry -- a per-tenant clickhousewriter.Writer registry -- swapped in as the writer. A batch pulled from the single shared Redpanda topic can mix records from many tenants, so WriteBatch groups by TenantID and dispatches each group to its own tenant's connection, fail- closed on an empty or unrecognized tenant_id. ingest/consumer and ingest/clickhousewriter move out of internal/ (same reason api/internal/* moved earlier this phase: enterprise/ can't import anything under another module's internal/). Their New() constructors now take small local Config structs instead of ingest/internal/config types, so enterprise/ doesn't need that import either. Building this surfaced a real bug: tenantprovision.ProvisionClickHouse only granted SELECT on a tenant's ClickHouse user, correct for chrunner's read-only use but not enough for chwriter reusing the same credential to write -- every real per-tenant write would have failed closed with a permission error. Fixed by widening the grant to SELECT, INSERT; no cross-tenant boundary is crossed by also allowing INSERT within a tenant's own database. Helm gates enterprise-ingest's Deployment on the same ingest.requireTenantCredential flag that already gates tag validation -- write-routing is meaningless without tagging already being required, so they're one decision, not two. docker-compose.yml's version is a disclosed, weaker approximation: it can't achieve Helm's genuine -mode=server/-mode=consumer split, so with the enterprise profile active both ingest and enterprise-ingest independently consume every message via different consumer groups -- harmless duplication for local verification only. Not built: Tantivy's independent Redpanda consumer (search/src/consumer.rs) still doesn't read the tenant_id header at all -- every record still lands in the one shared index regardless of tenant. Not run: the live-ClickHouse- gated tests (chwriter's cross-tenant routing test, tenantprovision's INSERT regression test) -- no Docker/database access in this environment; they're correct Go that has never executed, disclosed as such in docs/security/ threat-model.md and docs/phase-4-runbook.md §14. |
||
|
|
823f5d48d1 |
Unify the Tenant CRD with enterprise-api -provision-tenant (lightweight)
Closes a gap named across CLAUDE.md/docs/architecture.md/deploy/README.md
since early Phase 4: the operator's Tenant CRD and -provision-tenant
were two disconnected mechanisms. The operator's reconciler generated a
K8s Secret with a locally-generated random password that authenticated
against nothing (nothing ever called ClickHouse to create a matching
user), and unconditionally claimed status.phase=Active the moment a
Tenant object existed -- actively misleading, not just incomplete.
Two unification shapes were considered (surfaced to the user via
AskUserQuestion, given the real difference in blast radius): the
operator's reconcile loop becoming a second real actor (new Postgres +
ClickHouse admin credentials flowing into the K8s controller, plus real
reconcile-loop idempotency/retry design for an inherently one-shot
external side effect), or keeping -provision-tenant as the sole real
actor and having it also sync its result into the CRD. Went with the
lighter option.
enterprise/internal/tenantcrd (new): a Syncer using the K8s dynamic
client (unstructured.Unstructured + a GroupVersionResource, not
deploy/operator's typed Tenant struct -- avoids a cross-module Go
dependency between two independently-versioned modules for one type).
Upserts the Tenant object, creates/updates a Secret with the *real*
ClickHouse credentials owned by that Tenant via an OwnerReference, then
patches status.{clickHouseDatabaseName,clickHouseSecretRef,
tantivyIndexPath}. Idempotent and safe to retry: never rotates a
credential across a re-sync, never overwrites a pre-existing
spec.displayName a human/GitOps process set.
cmd/enterprise-api/main.go's runProvisionTenant calls Sync when
TENANT_CRD_NAMESPACE is set (empty = no-op, same shape as every other
optional dependency in this codebase). Its "already active" refusal is
now split: ClickHouse re-provisioning is still refused (rotating a live
credential would break every open connection for no benefit), but CR
sync alone is now retryable using the credentials already on file in
rbacstore -- needed for retrying a previously-failed sync, or
backfilling CR sync for a tenant provisioned before this existed.
deploy/operator's reconciler rewritten to match: it never claims
PhaseActive on its own initiative anymore, only once
status.ClickHouseDatabaseName is non-empty (the field -provision-tenant,
and only -provision-tenant, sets). Phase is now a pure function of
{spec.suspended, status.ClickHouseDatabaseName != ""} recomputed every
reconcile, not toggled in place -- fixes a related bug the old code
would have hit once suspension was involved: un-suspending an
already-provisioned tenant needs to return straight to Active, which
isn't derivable from "last observed phase was Suspended" alone. The
reconciler no longer creates or manages any Secret, dropped its
`secrets` RBAC grant entirely, and gained zero new dependencies.
Helm chart: enterprise-api gets its own ServiceAccount/Role/RoleBinding
(get/list/create tenants, get/update/patch tenants/status, get/create/
update secrets -- least-privilege, scoped to the release namespace, not
a ClusterRole) and a TENANT_CRD_NAMESPACE env var, both gated on
tenantOperator.enabled. tenant-operator's ClusterRole loses the
secrets grant it no longer needs.
Verified in this environment: enterprise/internal/tenantcrd's tests run
against k8s.io/client-go's fake dynamic + typed clientsets (real client
library, fake transport, no cluster needed); deploy/operator's rewritten
tenant_controller_test.go runs against controller-runtime's fake
client, including new regression tests for the "must not claim Active
without confirmation" and "un-suspending returns to Active, not
Provisioning" properties; helm template + parsing the rendered YAML
confirms the RBAC split renders exactly as designed under both
tenantOperator.enabled=true/false. Not verified: an actual
-provision-tenant run against a real cluster with the operator watching
(no live cluster in this environment, same disclosed limitation as the
rest of /deploy). Docs updated in lockstep: CLAUDE.md, docs/architecture.md,
deploy/README.md, deploy/helm/sentry/README.md (including a corrected
"Trying the two-tenant example" walkthrough), phase-4-runbook.md (new
§11), enterprise/README.md. Also fixed two unrelated stale claims found
along the way: docs/architecture.md still said docker-compose.yml ran
plain api unconditionally (fixed in an earlier commit, doc not updated
then), and enterprise-api's own main.go doc comment still said Helm/
docker-compose wiring wasn't built yet.
|
||
|
|
1d57e697b1 |
Phase 4: real per-tenant ClickHouse isolation via a new enterprise-api binary
Closes the threat model's headline finding for the SQL query path:
enterprise/internal/tenantprovision does real CREATE DATABASE/USER/GRANT
against ClickHouse, and enterprise/internal/chrunner is a per-tenant
connection registry implementing api's SQLRunner interface, resolving
the tenant from the authenticated request identity -- never a
caller-suppliable parameter. Both are wired into a new binary,
enterprise/cmd/enterprise-api, alongside the unchanged single-tenant
api/cmd/api, since AGPL core can never import enterprise/ and Go's own
internal/ package visibility rules meant enterprise/ couldn't implement
core's SQLRunner interface without importing the package that defines
it. That required moving api/internal/{authz,queryapi,dashboards,
querylang/executor,searchclient,httpserver} out of internal/ -- the
minimal set enterprise-api needs to import; querylang's compiler
internals (planner/lexer/parser/ast/ir) and api's own config stay
internal, since nothing outside api needs them directly.
Also finally wires enterprise/internal/audit into queryapi.AuditLogger
(nil since Phase 4 task 4) via a new adapter, and adds live-ClickHouse
integration tests for two of the four adversarial probes named in
docs/phase-4-isolation-design.md's verification plan.
Corrected several overclaims in the docs while writing this up: an
earlier claim that rbacstore's CRUD was "verified against a live
Postgres" was never actually true in this environment (only
internal/audit was, earlier in this phase, before Docker access was
lost) -- threat-model.md, phase-4-runbook.md, CLAUDE.md, and
enterprise/README.md all now distinguish "a real integration test
exists" from "this was confirmed against a live database."
Still not built: Tantivy/free-text tenant isolation
(enterprise/internal/searchclient), and any deployment-topology
mechanism that actually routes traffic to enterprise-api instead of
plain api -- both binaries exist side by side today with nothing
enforcing or flagging which one a deployment runs.
|
||
|
|
3eb0f4c589 |
Phase 4: SSO scaffolding, RBAC enforcement, tenant-scoped dashboards, audit logging, K8s deployment
RBAC (api/internal/authz) is live on /query and /dashboards, backed by a new enterprise/ module (session issuance, audit logging, RBAC storage, OIDC/SAML protocol wiring) that core never imports -- only calls over HTTP. Found and fixed a real cross-tenant vulnerability in dashboards (no tenant_id filtering at all) while writing the threat model doc. Two things are explicitly NOT done, documented rather than hidden: tenant isolation for log data itself (/query still shares one ClickHouse connection and Tantivy index across every tenant -- RBAC controls who can query, not what a query can see), and human SSO login (protocol wiring exists, no HTTP handler calls it yet). See docs/security/threat-model.md and docs/phase-4-runbook.md. Also adds deploy/ (Go Operator + Helm chart, validated offline only -- no cluster was reachable in this environment). |