Skip to content

Add authorized runtime GraphQL reads and confidential cursors (PR C) [skip ci] - #114

Merged
Dastari merged 8 commits into
mainfrom
feat/runtime-graphql-reads-20261009
Oct 12, 2026
Merged

Dastari merged 8 commits into
mainfrom
feat/runtime-graphql-reads-20261009

Conversation

@Dastari

@Dastari Dastari commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Summary

Add opt-in runtime GraphQL reads over the existing validated schema, typed query and relation executors. Per-execution preflight authorizes every selected ORM layer before the first ORM statement; grants restrict reads/counts structurally. Named objects, recursive filters, ordering, connections and bounded relation batches share checked composition with host-owned types/fields.

Custom scalars preserve full i64 and JSON-text values, including JSON null versus SQL NULL. Host-managed AEAD protects complete internal cursor envelopes; trusted audience, authority partition, schema, order and parent scopes are authenticated. Static SDL, framework-neutral cursors and default features remain unchanged. No data migration is required.

Dependent C implementation, ready for review; not yet an accepted D predecessor. Base is accepted B 04a1216aff86141ff6500b1dd0bf9adb4b0c6447 (#113). Current implementation head is 9d4cca34cb04ab0fd27c8313215001591f495c43. ORM/macros are aligned at unpublished 0.42.0. Enable sqlite,runtime-graphql or postgres,runtime-graphql with default features disabled.

Approved custom-directive limitation

The owner approved a bounded adjustment to #86: locked async-graphql 7.2.1 does not expose dynamic custom-directive factory registration. RuntimeGraphqlComposer::directive(factory) now returns structured unsupported_capability during composition, before schema publication, without invoking or silently ignoring the factory. The canonical C contract and capability reference record this limitation. Custom directives remain deferred; no fork, upgrade or emulation.

Focused tests execute host subscriptions and built-in directives, check subscription-root collisions and directive limits, and verify immediate factory rejection. Host extensions and mandatory authorization/resource guards remain intact.

C1/C2 re-review corrections

  • C1: scalar/helper data retains schema-field identity; relation data uses a disjoint schema-field/response-alias key. Resolvers and response-size accounting use the same lookup. Regression assertions cover scalar swaps, scalar/relation overlaps in both directions, connection/page-info helpers, fragments, to-one relations and exact response-budget boundaries.
  • C2: requested field/operator and explicit logical capabilities are retained before typed predicate constant lowering. Empty in remains false and empty notIn remains true, but neither bypasses authorization. SQLite/PostgreSQL cases assert denied nested filters execute zero ORM statements, allowed filters retain results/counts, and the authority receives exact field/operator/logical intent.

Public APIs and example

RuntimeGraphqlModule::compile, RuntimeGraphqlComposer, RuntimeHostField, RuntimeGraphqlRequest, RuntimeReadAuthority/RuntimeReadGrant, and RuntimeCursorProtector provide the host boundary. See docs/reference/graphql-orm/runtime-graphql.md and the executable crates/graphql-orm/examples/runtime_graphql_reads.rs. An external consumer executes the same example without a direct async-graphql dependency.

Verification

Actions remain paused; commits use [skip ci]. Local builds use CARGO_BUILD_JOBS=2, sequential backend lanes and disk-backed scratch. SQLite resources are test-owned in-memory databases. PostgreSQL execution uses disposable Docker containers whose exact IDs/ownership labels are verified before removal.

Final local evidence at 9d4cca34cb04ab0fd27c8313215001591f495c43:

  • SQLite: 65 passed, 0 ignored. Includes 40 library tests, C GraphQL execution, static naming, existing runtime reads/relations and 20 B mutation/cancellation tests. C itself contributes eight unit cases plus one database integration case with multiple acceptance assertions.
  • PostgreSQL: 62 passed, 0 ignored. Includes 39 library tests, two C execution cases (including a restricted RLS role) and 21 owned-database B tests. C itself contributes eight unit cases plus two database integration cases. String/CAS subcases gated on Fix runtime string predicates and PostgreSQL native parameter binding #112 remain unexecuted; zero ignored tests is not a claim that those branches ran.
  • Both C fixtures measure four data statements for two parent pages/counts plus batched child pages/counts, and three for a three-level traversal. Denied nested selections execute zero statements. Wrong-parent cursor resume executes the authorized parent read but no child query.
  • Confidential framing, tampering, raw cursor rejection, wrong schema/order/audience/authorization partition, rotation/retirement, forward/backward/nested resume, policy changes, alias/fragment authorization, projection/filter/operator/order/count denial, JSON-null states, i64 extrema, bytes and datetime precision pass.
  • Host extensions cannot bypass preflight by replacing parsed selections. Generated runtime objects require private authorized payloads; arbitrary preloaded/forged host Values fail safely. Authority distinguishes client ordering from effective internal keys and sees logical predicate operators.
  • The external host example compiled and executed on SQLite and owned PostgreSQL without a direct async-graphql dependency. Feature-off plain repository consumers also compiled on both lanes.
  • Scoped warnings-denied Clippy and Rustdoc passed for core/macros on SQLite, PostgreSQL and MSSQL. SQLite+MSSQL coexistence compiled. MSSQL's lazy-pool rejection test passed (one test); no live MSSQL execution.
  • cargo fmt --all -- --check passed. Strict default/static semver comparison against B passed 223 checks; 30 inapplicable checks skipped, with isolated current/baseline outputs confirming 0.41.0 → 0.42.0. The shared-target attempt was discarded because its summary mislabeled the current version.
  • Documentation validation passed for 194 governed files; inventory, dependency direction, package release policy, release-state (9 packages), release-manifest (6 checks) and PR documentation-impact checks passed.
  • One offline federation-fixture metadata attempt lacked cached android_system_properties; the explicit Linux target metadata check passed. No Android/Windows build is claimed.
  • The upstream dynamic-builder directive probe fails E0599 as expected. The approved ORM composition-time rejection is separately executed and passes.
  • Hosted Actions: not run; queried head currently has zero workflow runs.

Primary execution commands:

cargo test -p graphql-orm --locked --no-default-features --features sqlite,runtime-graphql --lib --test runtime_graphql --test graphql_naming --test runtime_queries --test runtime_relations --test runtime_mutations -- --test-threads=1
cargo test -p graphql-orm --locked --no-default-features --features postgres,runtime-graphql --lib --test runtime_graphql --test runtime_mutations -- --test-threads=1
cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features sqlite,runtime-graphql --example runtime_graphql_reads
cargo run --manifest-path crates/graphql-orm/tests/fixtures/repository-aggregate-consumer/Cargo.toml --locked --no-default-features --features postgres,runtime-graphql --example runtime_graphql_reads
cargo test -p graphql-orm --locked --no-default-features --features mssql,runtime-graphql --test runtime_graphql_unsupported
cargo clippy -p graphql-orm -p graphql-orm-macros --locked --no-default-features --features sqlite,runtime-graphql --lib --test runtime_graphql --example runtime_graphql_reads -- -D warnings
RUSTDOCFLAGS=-Dwarnings cargo doc -p graphql-orm -p graphql-orm-macros --locked --no-default-features --features sqlite,runtime-graphql --no-deps
env -u CARGO_TARGET_DIR cargo semver-checks -p graphql-orm --manifest-path crates/graphql-orm/Cargo.toml --baseline-rev 04a1216aff86141ff6500b1dd0bf9adb4b0c6447 --default-features --release-type patch

Clippy/Rustdoc were repeated sequentially with postgres,runtime-graphql and mssql,runtime-graphql; the MSSQL Clippy target was --lib --test runtime_graphql_unsupported. All commands used the bounded two-job environment. Public API examples and exact wire forms are in the reference linked above.

Compatibility and release boundaries

  • MSSQL is unsupported for runtime row decoding and is rejected before pool acquisition. Compilation/pre-I/O rejection is not live MSSQL execution.
  • Custom-directive factories are explicitly unsupported and rejected during composition, per the approved adjustment. D is not included and remains gated on reviewed C/B.
  • Fix runtime string predicates and PostgreSQL native parameter binding #112 is not in this unreconciled stack. Successful PostgreSQL string/CAS and SQLite empty-suffix behavior still require reviewed Fix runtime string predicates and PostgreSQL native parameter binding #112 → A → B → C reconciliation; existing gated subcases are not passing evidence.
  • Pages/counts retain existing backend isolation behavior, not a frozen snapshot across concurrent writes, aliases or nested layers. Counts can scan many database rows; hosts configure database timeouts.
  • Digibase integration after review/release: enable the selected backend plus runtime-graphql; compile its validated Arc schema; install a host AEAD provider/audience; attach fresh request authority, expected schema fingerprint, trusted authorization partition and optional PostgreSQL DbAuthContext. Grant client projection/filter/logical-operator/order/relation/count capabilities explicitly, returning current SQL-renderable row restrictions. Keep the host's complete public/policy revision checks and key management outside ORM. Run downstream confidential-cursor, authorization, scalar and SQLite/PostgreSQL read/count contracts before adoption.
  • No merge, publication, immutable release identity or downstream adoption is claimed. Owner merge/release order remains Fix runtime string predicates and PostgreSQL native parameter binding #112 then final A/B/C reconciliation. Digibase should pin only reviewed released source and run its own SQLite/PostgreSQL contracts.
  • Original, A and B worktrees remain untouched. No sibling repository changes.

Documentation impact

  • Documentation updated
  • No documentation impact

Explanation: added the runtime GraphQL reference and compiled host example, indexed the reference, updated the approved plan's current checkpoint, changelog, migration guide and generated package inventory. The approved directive limitation and supported-composition tests are explicit.

Retain exact tested reconciliation tree 15f06d5. No source deviation.
@Dastari
Dastari changed the base branch from feat/runtime-mutations-20261007 to main October 12, 2026 00:05
@Dastari
Dastari marked this pull request as ready for review October 12, 2026 00:05
@Dastari
Dastari merged commit 9478b69 into main Oct 12, 2026
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.

1 participant