Files
narratio/docs/roadmap/notarius-credential-forwarding.md

13 KiB

Typed Notarius Credential Forwarding

Status: Complete — 2026-09-16

Summary

Allow an operator to configure one typed credential reference for the Notarius 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.

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 owns execution order and concrete implementation steps.

Problem

An enabled Notarius pipeline may select a PromptKit profile that requires an API key, such as a profile whose api_key_env is OPENROUTER_API_KEY. Narratio already supports environment and secrets-directory bootstrap for typed credentials, but the Notarius configuration section has no credential field.

Consequently, an operator cannot declare the Notarius credential dependency in Narratio configuration. Supplying the variable to Narratio's environment or conventional secrets directory is not sufficient under the current public contract: the Notarius invocation receives Narratio's minimal child environment, and no selected Notarius credential is forwarded.

This leaves an otherwise valid configured extraction stage unable to authenticate to a provider without an out-of-band invocation mechanism.

Required Operator-Facing API

Add one optional typed secret reference at:

pipeline.notarius.llm_api_key

Illustrative addition to an otherwise valid pipeline:

notarius:
  llm_api_key: OPENROUTER_API_KEY

llm_api_key contains an environment-variable name, never a raw credential. Its value uses the same typed-secret and ConfigKit bootstrap semantics as other Narratio credential references:

  • when the field is absent, Narratio forwards no Notarius credential and preserves the current behavior;
  • when the field is present, its value must be a valid typed secret reference that resolves to a nonempty credential during configuration loading;
  • an existing process environment value takes precedence over a value loaded from the selected secrets directory;
  • --secrets-dir and conventional sibling secrets/ discovery retain their existing meanings; and
  • 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 selected by the Notarius PromptKit profile without introducing provider-specific configuration in Narratio.

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, configuration internals, and adapter internals remain the canonical owners of the implemented system's boundaries.

Inspection and Diagnostic Contract

  • narratio config validate resolves the configured secret reference and fails before stage execution when it is missing or empty.
  • narratio config show may expose the non-secret reference name, such as OPENROUTER_API_KEY, but never the resolved credential value.
  • narratio config sources and narratio config diff retain their existing secret-safe behavior.
  • Configuration digests, manifests, generated configuration, command arguments, persisted diagnostics, receipts, and other operator-visible output must not contain the resolved credential value.
  • 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 their current behavior without migration.

The credential name belongs to deployment configuration rather than to a specific provider. Narratio does not infer a name from a Notarius pipeline, profile ID, backend, model, or configuration file. Operators must select a name that agrees with the Notarius PromptKit profile they deploy.

Acceptance Criteria

  • A pipeline with Notarius enabled and no notarius.llm_api_key continues to load and invoke Notarius with no forwarded provider credential.
  • A pipeline may set notarius.llm_api_key to a valid environment-variable reference.
  • The reference resolves from an existing process environment value or from Narratio's existing explicit or conventional secrets-directory bootstrap.
  • A missing or empty configured credential fails configuration loading before Notarius execution.
  • A successful Notarius invocation receives the resolved value under exactly the configured reference name.
  • Unrelated credentials present in Narratio's environment or secrets directory are not made available to Notarius merely because this field is configured.
  • Base and named-profile configuration follow ordinary ConfigKit replacement, 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 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; they do not contact a model provider or require a real API key.
  • Configuration, CLI, integration, example, troubleshooting, and release 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 and the normal development 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

  • 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 Notarius configuration.
  • Managing secret files, credential values, rotation, encryption, or an external secret store.
  • Changing Notarius configuration syntax, PromptKit profile syntax, CLI flags, receipt schemas, pipeline definitions, or output bundles.
  • Supporting more than one Notarius provider credential in this feature.
  • 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

The D&D Ansible pipeline requires this operator-facing contract before it can provide complete suite-managed credential delivery. Its intended deployment places files named for configured secret references in Narratio's conventional secrets/ directory. That deployment can select and provision the value only after Narratio provides a typed field that forwards the selected Notarius credential under the same reference name.