[codex] Prepare Osprey sandbox deployment#1
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Prepare Osprey for a Coolify-hosted sandbox deployment and customer handoff.
This PR hardens the sandbox API path, Docker runtime, customer documentation, and assurance workflow so Osprey can be deployed as a Dockerfile app and later verified at
sandbox.osprey.opensource.financeafter DNS/Coolify are live.What Changed
/evaluate, persistence, tenant isolation, duplicate transaction handling, JSON validation, rule/typology mutation, and admin-token protection./app/datavolume, healthcheck, reproducible build args, and env templates.assure-sandbox.sh,verify-sandbox.sh, build-arg helper, and a GitHub Actions gate.Validation
Latest full local gate passed:
That covered JSON examples, OpenAPI contract checks, docs links, Coolify templates, shell syntax,
go test ./...,go vet ./...,go test -race ./..., HTTP integration tests, Docker build, Docker image metadata, and Docker-backed sandbox verification.Deployment Note
Public verification at
https://sandbox.osprey.opensource.financeis intentionally not part of this PR evidence yet because the domain has not been deployed/configured in Coolify. After deployment, run:Greptile Summary
This PR prepares Osprey for a customer-facing Coolify sandbox deployment by hardening the API, adding Docker runtime hardening, tenant/duplicate-transaction enforcement, admin-token protection, and an extensive assurance gate. The scope is large (42 files, ~4500 net additions) spanning runtime Go changes, a SQLite schema migration, shell scripts, and new documentation.
TransactionRequest/EvaluationResponsetypes intohandler.go, adds body-size limiting,DisallowUnknownFields, RFC3339 timestamp parsing, duplicate-transaction detection against the new composite PK, and full CRUD for rules/typologies with live engine reload behindAdminMiddleware.transactionstable to a compositePRIMARY KEY (id, tenant_id)via an in-place SQLite migration and fixes all previously-silencedjson.Unmarshalerrors throughout the repository layer./app/datavolume, reproducible build-arg injection, and a working healthcheck; a new GitHub Actions workflow drives the full assurance suite on every PR.Confidence Score: 3/5
Not safe to merge to a customer-facing sandbox in its current state — the admin mutation endpoints are unprotected when the token env var is absent, and the duplicate-transaction check can return 500 under concurrent load where it should return 409.
The Evaluate handler performs a non-atomic GetTransaction → SaveTransaction check; under concurrent duplicate submissions the DB constraint fires instead, and the handler surfaces a 500 rather than the intended 409. DeleteTypology maps every repository error (including real DB failures) to 404, hiding operational problems from callers. AdminMiddleware has an explicit no-op path when the token is unconfigured, leaving all rule and typology mutation endpoints wide open on any deployment that omits the env var — a realistic risk for a sandbox handed to a customer without a hardening checklist being followed.
internal/api/handler.go (TOCTOU race and DeleteTypology error mapping), internal/api/middleware.go (AdminMiddleware bypass and misleading 401 message), internal/repository/repository.go (migration silent-skip edge case)
Security Review
AdminMiddlewareis a transparent pass-through whenOSPREY_ADMIN_TOKENis empty. Any caller can inject or overwrite CEL rule expressions into the live evaluation engine viaPOST /rules,PUT /typologies/{id}, etc. This is insecure by default for a customer-facing deployment.Access-Control-Allow-Origin: *combined withX-Osprey-Admin-TokeninAccess-Control-Allow-Headersmeans any browser origin can preflight and issue admin requests if the token is known or absent.Important Files Changed
Sequence Diagram
sequenceDiagram participant Client participant CORS as CORSMiddleware participant Tenant as TenantMiddleware participant Admin as AdminMiddleware participant Handler participant Repo as SQLRepository participant Engine as RulesEngine Client->>CORS: POST /evaluate (X-Tenant-ID) CORS->>Tenant: pass Tenant->>Handler: ctx + tenantID Handler->>Repo: GetTransaction(tenantID, txID) Note over Handler,Repo: TOCTOU: not atomic with SaveTransaction Repo-->>Handler: ErrNotFound Handler->>Repo: SaveTransaction(tenantID, tx) Repo-->>Handler: ok Handler->>Engine: EvaluateAll(input) Engine-->>Handler: ruleResults Handler->>Repo: SaveEvaluation(tenantID, eval) Repo-->>Handler: ok Handler-->>Client: 200 EvaluateResponse Client->>CORS: POST /rules (X-Osprey-Admin-Token) CORS->>Tenant: pass Tenant->>Admin: AdminMiddleware Note over Admin: No-op if token empty (insecure by default) Admin->>Handler: CreateRule Handler->>Engine: ValidateRule + ReloadRules Handler-->>Client: 201 CreatedPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "Prepare Osprey sandbox deployment" | Re-trigger Greptile