Skip to content

chore(local): add local Oracle dev/test harness - #545

Draft
wz-gsa wants to merge 8 commits into
mainfrom
chore/local-dev-harness
Draft

chore(local): add local Oracle dev/test harness#545
wz-gsa wants to merge 8 commits into
mainfrom
chore/local-dev-harness

Conversation

@wz-gsa

@wz-gsa wz-gsa commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Split out of #537 to keep that PR focused on the shipping broker code.

Adds a docker-compose-based local harness for developing/exercising the Oracle work locally. Dev signal only — never compliance evidence (live GovCloud RDS proof is separate).

  • moto for the RDS control-plane request-shape smoke.
  • gvenzl/oracle-free + an Oracle 19c compose for the SQL hardening/assessment loop.
  • A Makefile (doctor/quickstart/unit/moto-smoke); assess -> harden -> assess runs inside the container via docker exec (no host Oracle Instant Client required).
  • local/README.md documents the overlay-sibling-clone requirement.

Touches only local/; no application or CI-pipeline changes.

Closes

Closes #529 (WS10/11 — Oracle 19c: SQL hardening package + local test harness). The authoritative SQL lives in the overlay repo; this is the local dev loop for it.

@wz-gsa
wz-gsa requested a review from a team as a code owner July 21, 2026 18:42
@wz-gsa
wz-gsa force-pushed the chore/local-dev-harness branch from 8f5052d to e1eb5b9 Compare July 21, 2026 20:40
@wz-gsa

wz-gsa commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

Ran a hostile self-review and fixed the findings (pushed):

  • MEDIUM — LAN exposure. All three compose files published ports on 0.0.0.0 (Oracle 1521/1522, moto 5000) with a known local-only password. Now bound to 127.0.0.1 only, with a comment warning not to revert.
  • LOW — reports/ not actually gitignored despite the README claiming so. Added local/.gitignore that ignores reports/ (dev-signal output, never commit).
  • LOW — dangling references. The init/*.sql seed scripts the README/compose reference weren't actually included, so oracle-up silently didn't seed the non-SYS user + weak state. Added them (force-tracked past the global *.sql ignore).
  • LOW — reproducibility. Pinned motoserver/moto:5.2.2 (was :latest).
  • Swept ephemeral tokens (ADR/WS/issue refs to docs that live on other branches) out of the local/ comments so nothing dangles.

Verified: compose YAML parses, ports bind loopback-only, reports/ ignored while init/*.sql tracked.

Add a docker-compose-based local harness (dev signal only, never compliance
evidence): moto for the RDS control-plane request-shape smoke, and
gvenzl/oracle-free + oracle-19c for the SQL hardening/assessment loop, driven by
a Makefile (doctor/quickstart/unit/moto-smoke). assess->harden->assess runs
inside the container via docker exec (no host Instant Client). README documents
the overlay-sibling-clone requirement.

Security/hygiene:
- All published ports bind to 127.0.0.1 only (Oracle 1521/1522, moto 5000) so the
  dev DB with its known local-only password is never reachable from the LAN/VPN.
- moto image pinned to 5.2.2 (was :latest) for reproducibility.
- local/.gitignore ignores generated reports/ (dev-signal output, never commit)
  and force-tracks init/*.sql past the global *.sql ignore; the referenced
  init seed scripts are now included so oracle-up actually seeds the non-SYS user
  + weak state the README describes.
@wz-gsa

wz-gsa commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

📋 Merge order: 2️⃣ of 4 (local dev/test harness — local/ only, pipeline-inert).
Coordinated set; full order + status board: #550

Rename terse variables in moto-smoke.sh for readability:
EP -> MOTO_ENDPOINT, ID -> INSTANCE_ID, PG -> PARAM_GROUP,
OG -> OPTION_GROUP. No behavioral change.
Add a note that make commands run from the repo root (with the
in-local alternative), and render the layer-3 clone layout with
tree connectors and a <workspace> root label.
The development-signal-only caveat is covered by the local/README.md
banner and the harness Makefile; the per-script line was redundant.
Layer-1 unit tests pull in go-sqlite3 (a cgo package) and segfault
under the default CGO_ENABLED=0; force CGO_ENABLED=1 in the harness
Makefile so 'make unit' works out of the box.

Add a doctor check for a C compiler (cc/gcc/clang) as a hard layer-1
prerequisite, upgrade the aws check to 'MISSING for layer 2', and give
both macOS and Linux install hints. Broaden the prereqs header/table to
cover macOS arm64 and Linux.
The 'brew install --cask cinc-auditor' guidance was outdated: we run
cinc-auditor via Docker to avoid the cinc-workstation install (needs
root). Update the doctor check and README prereqs/§3 to use a
'docker run cincproject/auditor' recipe, noting the overlay derives an
image with Oracle Instant Client for its sqlplus-based oracledb_session
controls.
The single-shot curl check raced 'make moto-up': the container's HTTP
listener can lag a beat behind 'docker compose up -d' returning, so
back-to-back moto-up && moto-smoke failed on the first miss. Poll
:5000 once per second up to MOTO_TIMEOUT (default 10s) instead.

Co-authored-by: OpenCode Agent <peter.burkholder@gsa.gov>
@pburkholder

Copy link
Copy Markdown
Contributor

Proposed ADR (for discussion): Drop the local Oracle 19c Enterprise Edition image from the test harness

Posting this as a comment for discussion. If we ratify it, the accepted ADR
should land in docs/adr/0001-*.md per the workspace standard so the rationale
is durable.


---
title: "Drop the local Oracle 19c Enterprise Edition image from the test harness"
status: "proposed"
date: "2026-07-23"
decision_makers: ["Peter Burkholder"]
category: "development-tooling"
nist_controls: ["CA-2", "SA-11", "SA-15", "CM-2"]
impact_level: "moderate"
ato_relevance: "no"
risk_treatment: "accept"
---

Context and Problem Statement

The local/ test harness offers an optional "layer 3 fidelity" tier backed by a
self-built oracle/database:19.3.0-ee image (local/docker-compose.oracle-19c.yml,
the oracle19c-up Make target). Building that image is high-friction and, on ARM64,
produces the wrong Oracle edition relative to the brokered product. Should we keep
this dependency or remove it and rely solely on the freely-pullable
gvenzl/oracle-free image for local development signal?

Decision Drivers

  • The brokered product is Oracle 19c Standard Edition 2 (SE2), License Included
    "License Included is SE2-only on RDS; Enterprise Edition is BYOL-only"
    (docs/oracle19c/design-notes.md, docs/oracle19c/licensing.md). The local EE
    image is therefore the wrong edition.
  • No local SE2 image is achievable on ARM64. Oracle's own builder refuses it:
    ./buildContainerImage.sh -v 19.3.0 -s
    "Currently only 19c enterprise edition and 26ai Free are supported on ARM64
    platform."
    The only ARM64 options are 19c EE and 26ai Free.
  • The EE image can exercise EE-only features (Oracle-native TDE, Fine-Grained
    Auditing)
    that SE2 lacks and that the design explicitly compensates for (RDS
    storage-level AES-256/KMS encryption in place of TDE; unified auditing in place of
    FGA — docs/oracle19c/licensing.md). Validating those paths locally risks a
    misleading green for behavior that will not exist on the real SE2 RDS instance.
  • Building EE requires authenticating to Oracle to download
    LINUX.ARM64_1919000_db_home.zip (~2.2 GB) or staging that file / image in a
    non-public store — operational and licensing friction for every developer.
  • Authoritative STIG-conformance validation happens on a real brokered GovCloud RDS
    SE2 instance regardless
    (per the overlay repo and
    docs/oracle19c/validation-contract.md). The local harness is explicitly labeled
    "development signal only — not compliance evidence."
  • gvenzl/oracle-free is freely pullable, native ARM64, and already the harness
    default (cg-oracle-free, FREEPDB1).

Considered Options

  1. Keep the 19c EE image — Maintain the self-built EE fidelity tier alongside
    oracle-free.
  2. Replace it with a local SE2 image — Match production edition locally.
  3. Remove the EE dependency; keep gvenzl/oracle-free (26ai) as the sole local
    engine
    — Document the version-fidelity caveat; rely on real RDS SE2 for
    authoritative validation.

Decision Outcome

Chosen option: Option 3 — remove the EE dependency and keep gvenzl/oracle-free,
because Option 2 is impossible on ARM64 (the builder supports only EE and Free),
and Option 1's marginal benefit (correct 19c version string) is outweighed by its
cost (auth/2.2 GB/private-registry friction) and its risk of validating wrong-edition
hardening paths. Edition-accurate conformance is proven on the real RDS SE2 instance
either way.

Positive Consequences

  • Removes a licensing- and bandwidth-encumbered build step; every developer can run
    layer 3 with a single free docker pull.
  • Eliminates the wrong-edition "misleading green" risk (TDE/FGA paths that SE2 lacks).
  • Simplifies local/ to a single Oracle engine (fewer compose files, Make targets,
    and README branches to maintain).

Negative Consequences

  • Loss of 19c version fidelity locally. gvenzl/oracle-free is the 23ai/26ai
    engine, not 19c; 19c-specific defaults, deprecated parameters, or profile behavior
    will not be exercised locally. This gap is accepted because local layer 3 is
    development signal only.
  • Anyone wanting a true 19c engine locally must build EE manually (still possible;
    just no longer wired into the harness).

Compliance Consequences

  • No ATO-boundary impact: this is local developer tooling, not part of the
    authorization boundary, and produces no compliance evidence (CA-2 evidence still
    comes from the RDS SE2 run).
  • CM-2 / documentation: remove the three local/ references (compose file,
    Makefile oracle19c-up/COMPOSE_ORACLE19C/down, README layer-3 build section)
    so the harness inventory has no dangling EE mentions.
  • SA-11 / SA-15: the run-and-verify story is unchanged — unit + moto + local
    oracle-free remain; authoritative STIG validation remains on real RDS SE2.
  • Confirm PR feat(oracle19c): STIG-hardened Oracle Database 19c brokered RDS support - DEV branch #537's docs/oracle19c/ do not promise a local 19c parity pass before
    that PR merges, so the documented validation strategy stays consistent.

Links

No local SE2 image is possible on arm64 — Oracle's buildContainerImage.sh
supports only 19c EE and 26ai Free ('-s' errors out). An EE image is the
wrong edition (exposes EE-only TDE/FGA that the brokered SE2 lacks and the
design compensates for), risking a misleading local pass. Edition-accurate
STIG conformance is validated on a real brokered RDS SE2 instance regardless,
so the harness keeps only the freely-pullable gvenzl/oracle-free (23c) engine.

Remove docker-compose.oracle-19c.yml, the oracle19c-up target + COMPOSE_ORACLE19C
var + down/quickstart references, and retitle the README to state the 23c engine
vs 19c-on-RDS target. Rationale captured in the README §3 note (docs/oracle19c/
updates deferred to #537, where those files live).

Co-authored-by: OpenCode Agent <peter.burkholder@gsa.gov>
@pburkholder

Copy link
Copy Markdown
Contributor

I don't think the above comment really needs to be documented beyond what's in the local/README.md file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants