fix(inbound-api): resolve InboundAPI-007 — remove unimplemented Database.Connection() script API from design doc (conflicts with script trust model)

This commit is contained in:
Joseph Doherty
2026-05-16 23:49:25 -04:00
parent 3d0c1c6963
commit a2f6c1b9b2
2 changed files with 26 additions and 26 deletions

View File

@@ -8,7 +8,7 @@
| Last reviewed | 2026-05-16 | | Last reviewed | 2026-05-16 |
| Reviewer | claude-agent | | Reviewer | claude-agent |
| Commit reviewed | `9c60592` | | Commit reviewed | `9c60592` |
| Open findings | 2 | | Open findings | 1 |
## Summary ## Summary
@@ -294,9 +294,9 @@ and `FilterCapsMaxRequestBodySizeFeature` added.
| | | | | |
|--|--| |--|--|
| Severity | Medium — verified real drift; left Open pending a design decision (see Resolution) | | Severity | Medium |
| Category | Design-document adherence | | Category | Design-document adherence |
| Status | Open | | Status | Resolved |
| Location | `src/ScadaLink.InboundAPI/InboundScriptExecutor.cs:188-203` | | Location | `src/ScadaLink.InboundAPI/InboundScriptExecutor.cs:188-203` |
**Description** **Description**
@@ -317,27 +317,20 @@ API.
**Resolution** **Resolution**
_Unresolved — left Open; needs a design decision the resolving agent cannot make._ Resolved 2026-05-16 (commit `<pending>`). The drift was confirmed real:
Re-triage 2026-05-16: confirmed against the current source — the drift is **real**. `InboundScriptContext` (`InboundScriptExecutor.cs:188-203`) exposes only
`InboundScriptContext` (`InboundScriptExecutor.cs:188-203`) exposes only `Parameters`, `Parameters`, `Route`, and `CancellationToken` — there is no `Database` member,
`Route`, and `CancellationToken`; there is no `Database` member, so a method script so a method script following the documented `Database.Connection("name")` API
following the documented `Database.Connection("name")` API fails to compile. would fail to compile. Resolution direction: the design doc is stale, not the
code. Implementing `Database.Connection()` would hand inbound API scripts a
This finding cannot be closed by the InboundAPI module agent for two reasons: *raw* MS SQL client, in direct tension with the ScadaLink script trust model
1. **Scope** — the alternative resolution (deleting the "Database Access" section) (scripts are forbidden `System.IO`, raw network, etc.; `ForbiddenApiChecker`
edits `docs/requirements/Component-InboundAPI.md`, which is outside the editable statically enforces this). Rather than carve a hole in the trust model, the
scope (`src/ScadaLink.InboundAPI`, `tests/`, this file only). "Database Access" section was removed from `docs/requirements/Component-InboundAPI.md`
2. **It is a genuine design decision.** Implementing `Database.Connection()` is not a and replaced with an explicit "No direct database access" note explaining that
mechanical fix: it hands inbound API scripts a *raw* MS SQL client. The ScadaLink scripts interact only through the curated `Route`/`Parameters` surfaces, and
script trust model (CLAUDE.md, Akka.NET conventions) forbids scripts from `System.IO` that any future data access must go behind a dedicated scoped helper added as an
and raw network access, and `ForbiddenApiChecker` (added for InboundAPI-005) now explicit design change. Code and doc now agree; no code or test change required.
statically blocks `System.Net`/`System.IO`. A raw `SqlConnection` is in clear
tension with that trust model, and the set of connection names a script may open,
read-only vs. read-write access, and connection lifetime/pooling all require a
design call. **Surface to the design owner:** decide whether `Database.Connection()`
is in scope — if yes, write a design note covering the trust-model carve-out and
then implement a `Database` member backed by a connection-factory service; if no,
delete the "Database Access" section from `Component-InboundAPI.md`.
### InboundAPI-008 — Inbound API endpoint not restricted to the active central node ### InboundAPI-008 — Inbound API endpoint not restricted to the active central node

View File

@@ -160,8 +160,15 @@ Inbound API scripts **cannot** call shared scripts directly — shared scripts a
- `Parameters["key"]` — Raw dictionary access. - `Parameters["key"]` — Raw dictionary access.
- `Parameters.Get<T>("key")` — Typed access (same API as site runtime scripts). See Site Runtime component for full type support. - `Parameters.Get<T>("key")` — Typed access (same API as site runtime scripts). See Site Runtime component for full type support.
#### Database Access > **No direct database access.** Inbound API scripts are not given a raw database
- `Database.Connection("connectionName")` — Obtain a raw MS SQL client connection for querying the configuration or machine data databases directly from central. > client. Handing a script a raw `SqlConnection` is in direct tension with the
> ScadaLink script trust model (scripts are forbidden `System.IO`, `Process`,
> `Threading`, `Reflection`, and raw network access; `ForbiddenApiChecker`
> statically enforces this). Scripts interact with the system only through the
> curated `Route` and `Parameters` surfaces above. If a method needs data from
> the configuration or machine-data databases, that access belongs behind a
> dedicated, scoped helper — not a general-purpose connection — and would be
> added here as an explicit design change.
### Routing Behavior ### Routing Behavior
- The `Route.To()` helper resolves the instance's site assignment from the configuration database and routes the request to the correct site cluster via the Communication Layer. - The `Route.To()` helper resolves the instance's site assignment from the configuration database and routes the request to the correct site cluster via the Communication Layer.