Plan Notarius credential forwarding

This commit is contained in:
2026-09-16 14:14:56 +00:00
parent cd75bf6d5a
commit 2d346733d6
2 changed files with 315 additions and 225 deletions

View File

@@ -1,6 +1,6 @@
# Typed Notarius Credential Forwarding
Status: proposed
Status: Accepted — implementation pending
## Summary
@@ -9,8 +9,12 @@ stage. Narratio resolves that reference through its existing ConfigKit secrets
bootstrap and supplies the credential to the Notarius subprocess under the
referenced environment-variable name.
This request defines only the operator-facing configuration and invocation
contract. It does not prescribe an internal implementation.
The target is a bounded configuration-and-adapter feature that reuses ConfigKit
typed secrets and Narratio's existing subprocess environment and redaction
support. No upstream change or general environment-management framework is
required. This roadmap owns the desired end state and policy; the
[implementation plan](implementation.md) owns execution order and concrete
implementation steps.
## Problem
@@ -36,21 +40,11 @@ Add one optional typed secret reference at:
pipeline.notarius.llm_api_key
```
Example:
Illustrative addition to an otherwise valid pipeline:
```yaml
notarius:
enabled: true
config_path: /usr/local/etc/notarius/config.yml
pipeline_id: dnd-session
llm_api_key: OPENROUTER_API_KEY
outputs:
spells:
lane_id: spells
media_type: application/json
schema_id: notarius.dnd.spells
schema_version: v1
module_key: dnd/spells
```
`llm_api_key` contains an environment-variable name, never a raw credential.
@@ -68,6 +62,12 @@ Narratio credential references:
- a selected profile may replace or explicitly remove the field under ordinary
ConfigKit overlay semantics.
An explicit null has the same credential-delivery meaning as absence. Every
non-null reference surviving the selected profile must resolve, including during
inspection or when extract will not execute. Unselected or removed base
references are not independently resolved. Do not introduce stage-dependent
secret loading or a second environment lookup at execution time.
For a configured reference such as `OPENROUTER_API_KEY`, the Notarius child
process receives the resolved credential under exactly that environment name.
This lets the operator coordinate the Narratio field with the `api_key_env`
@@ -78,6 +78,47 @@ No new CLI flag is required. The existing Notarius argument vector, pipeline
configuration path, working directory, reference bindings, receipt, and output
contracts remain unchanged.
## Required Architecture and Changes
### Configuration and inspection
Add an optional `*configkit.Secret` to `NotariusConfig`, following the existing
typed credential pattern. ConfigKit owns reference syntax, effective-profile
resolution, and access to the resolved value; the application continues to own
the one-per-invocation secrets-directory bootstrap. The field defaults to absent.
Extend the relevant safe configuration projections, serialization, provenance,
and tests so this field is visible by its public reference name. Review both
effective inspection and generated/persisted configuration paths; protecting
`config show` alone is insufficient. Do not serialize an adapter invocation
request or a raw credential-bearing structure for diagnostics.
### Extract and adapter delivery
Carry the optional credential through extract's existing Notarius invocation
boundary. Keep transport-specific environment construction in the Notarius
adapter and expose the resolved value only at the trusted delivery boundary.
Reuse the subprocess runner's `EnvOverrides` for the selected name/value pair
and `SensitiveEnvNames` to register that same name for redaction. Register custom
names as well as familiar provider names; the built-in sensitive-name list is
not sufficient for this feature.
The child retains Narratio's existing minimal inherited environment plus the
explicit credential override. There is no broad process-environment inheritance,
provider-name remapping, or forwarding of unrelated bootstrapped secrets. An
absent reference adds neither an override nor a credential requirement.
### Ownership
Keep configuration semantics in `internal/config`, bootstrap in `internal/app`,
invocation orchestration in `internal/stage`, and environment/redaction delivery
in `internal/adapters/notarius` and the shared subprocess boundary. Reuse the
existing helpers rather than introducing another secret resolver or redactor.
The [architecture policy](../policy/architecture.md),
[configuration internals](../internal/configuration.md), and
[adapter internals](../internal/adapters.md) remain the canonical owners of the
implemented system's boundaries.
## Inspection and Diagnostic Contract
- `narratio config validate` resolves the configured secret reference and
@@ -92,6 +133,39 @@ contracts remain unchanged.
- Errors may identify the field or unresolved environment-variable name but
must not include credential bytes.
The selected credential must receive the existing streaming redaction protection
on captured stdout and stderr, including logs, captured receipt output, and
stderr-derived errors on nonzero exit, timeout, or cancellation. Test the delivery
of the dynamically selected sensitive name; do not create a provider-specific
redaction exception or a second log-sanitization mechanism.
### Downstream responsibility boundary
Narratio must not place credential values in its authored configuration,
arguments, manifests, or metadata, and must redact the selected value from
subprocess streams it captures. Notarius remains responsible for keeping
credentials out of files it writes directly, including bundle artifacts and
diagnostics. Captured-stream redaction is not a filesystem sandbox and does not
guarantee sanitization of arbitrary downstream files or transformed/encoded
secret values. This feature does not add recursive scanning or rewriting of
Notarius output bundles. Such rewriting could corrupt valid artifacts and would
not establish a general non-disclosure guarantee.
## Resume and Configuration Identity
Authentication is operational configuration, not extraction content. Neither
the credential value nor its reference name becomes part of extract's semantic
resume fingerprint. Credential rotation, renaming, addition, or removal alone
must not invalidate a successfully recorded extraction or its dependents.
The effective configuration projection may include the public reference name,
so changing that name can appear in `config diff` and change the effective
configuration digest. Rotating only the resolved value must not change that
digest. Preserve the existing distinction between configuration provenance and
stage-owned resume evidence; do not add a blanket digest-based invalidation.
Normal configuration loading still requires any selected reference to resolve
even when the prior extraction can be reused.
## Compatibility
The field is optional and defaults to absent. Existing configurations retain
@@ -120,8 +194,16 @@ that agrees with the Notarius PromptKit profile they deploy.
explicit-null, source-reporting, diff, and secret-resolution semantics.
- Effective inspection exposes at most the safe reference name and never the
resolved value.
- No raw credential appears in command arguments, generated configuration,
manifests, receipts, persisted diagnostics, error messages, or test output.
- No raw credential appears in Narratio-authored command arguments, generated
configuration, manifests, metadata, or test output. Captured receipt/log streams
and errors redact the selected value within the responsibility boundary above.
- A custom environment-variable name not present in the built-in sensitive-name
list receives the same redaction protection as a known provider name, on both
successful and failing subprocess execution.
- Credential rotation or reference-name changes do not alter extract's semantic
fingerprint or invalidate a reusable extraction. Inspection reflects name
changes without revealing values; value-only rotation leaves the safe digest
unchanged.
- The existing Notarius CLI arguments and result-validation contract remain
unchanged.
- Focused tests use synthetic credentials and a controlled Notarius substitute;
@@ -130,10 +212,27 @@ that agrees with the Notarius PromptKit profile they deploy.
documentation are updated only where their existing canonical ownership
requires it when the feature is implemented.
Use focused behavioral tests at the configuration, extract/adapter delivery,
and captured-output boundaries. Retain shared subprocess tests for its generic
streaming guarantees rather than duplicating their full matrix. Verify the
assembled invocation with a controlled executable and synthetic credentials,
including proof that an unrelated credential is not forwarded. Follow the
[testing policy](../policy/testing.md) and the normal
[development validation](../development.md#validation); no live-provider
authentication is an acceptance gate.
## Target End State
An operator supplies a named API-key file through the existing secrets directory
or sets that environment variable, declares `notarius.llm_api_key`, and configures
the matching `api_key_env` in Notarius's selected PromptKit profile. Narratio
validates the reference, delivers only the selected credential to Notarius, and
keeps its own configuration and diagnostics credential-safe. Existing pipelines
need no migration, and changing authentication does not rerun completed analysis
work. No new CLI, dependency upgrade, or upstream feature is required.
## Non-goals
- Defining how Narratio implements credential resolution or subprocess
construction internally.
- Adding an arbitrary environment-variable map to the Notarius stage.
- Forwarding every variable loaded from the secrets directory.
- Inferring provider, backend, profile, model, or credential names from
@@ -146,6 +245,9 @@ that agrees with the Notarius PromptKit profile they deploy.
- Validating a credential with its provider during configuration loading.
- Adding credentials to command-line arguments, ordinary YAML values, or
generated invocation files.
- Scanning or sanitizing arbitrary files created directly by downstream tools.
- Changing resume semantics, pipeline path bases, artifact schemas, or the
existing minimal inherited subprocess environment.
## Consumer Dependency