Close Feature 0011 after remediation

This commit is contained in:
2026-09-16 21:37:17 +00:00
parent d2bd48cc99
commit 54a2362c02
5 changed files with 158 additions and 748 deletions

View File

@@ -1,6 +1,6 @@
# Feature 0011: Managed Pipeline Credentials and Notarius Reuse
Status: ready
Status: done
## Summary
@@ -78,19 +78,18 @@ retaining their existing independently overrideable variables.
credential location.
- Create that directory as the selected pipeline runtime user and group with
mode `0750`.
- Add one public `dnd_pipeline_secrets` mapping. Keys are environment-variable
names. A non-null string value means that the named credential file must be
present with that content; null means that the specifically named managed
credential file must be absent. An omitted key is unmanaged.
- Add one public `dnd_pipeline_secrets` mapping from environment-variable names
to string file contents. Each supplied entry means that the named credential
file must be present with that content; an omitted key is unmanaged.
- Default `dnd_pipeline_secrets` to an empty mapping so the role never invents
credentials and remains usable with externally prepared process environment
values.
- Validate selected keys as environment-variable names and reject empty
non-null values before constructing a destination path.
- Write non-null credential files as the selected runtime user and group with
mode `0640`, and remove only names explicitly assigned null.
- Validate selected keys as environment-variable names and values as strings
before constructing a destination path.
- Write supplied credential files as the selected runtime user and group with
mode `0640`.
- Suppress credential values from Ansible task output during validation,
creation, updates, and removal.
creation, and updates.
- Keep ordinary application configuration limited to non-secret credential
reference names.
- Coordinate Audita proposal and validation on the suite-default
@@ -110,8 +109,8 @@ retaining their existing independently overrideable variables.
Narratio's secrets bootstrap supplies the selected environment value and the
existing Scriptorium adapter passes that named credential to its child.
- Document the mapping interface, Ansible Vault inventory pattern, process
environment precedence, shared-group authorization boundary, explicit null
removal, application credential flow, and checkpoint-reuse policy.
environment precedence, shared-group authorization boundary, application
credential flow, and checkpoint-reuse policy.
- Add focused integration coverage using distinctive synthetic values and
native Narratio configuration loading. No default test contacts a model
provider.
@@ -167,21 +166,19 @@ The filenames are suite-selected reference names, never credential values.
The selected runtime user and group remain configurable through the existing
pipeline interface.
A consumer may keep encrypted values in inventory and select explicit removal
without embedding any value in ordinary configuration:
A consumer may keep encrypted values in inventory without embedding any value
in ordinary configuration:
```yaml
dnd_pipeline_secrets:
AUDITA_LLM_API_KEY: "{{ vault_dnd_audita_llm_api_key }}"
OPENROUTER_API_KEY: "{{ vault_dnd_openrouter_api_key }}"
RETIRED_PROVIDER_KEY: null
```
The role owns only these three named entries for this invocation. It converges
the first two to regular files, removes the third, and leaves every omitted
name alone. The actual `vault_dnd_*` values belong in encrypted inventory and
must not appear in examples, plans, test logs, commits, or ordinary generated
configuration.
The role owns only the supplied named entries for this invocation and leaves
every omitted name alone. The actual `vault_dnd_*` values belong in encrypted
inventory and must not appear in examples, plans, test logs, commits, or
ordinary generated configuration.
When Narratio runs without `--secrets-dir`, it discovers the sibling directory
and loads its immediate regular files before resolving the pipeline. An
@@ -252,8 +249,9 @@ and its existing adapter forwards the selected profile credential.
- Credential filenames must match the environment-variable grammar accepted
by ConfigKit. Validation exists to prevent a caller-controlled key from
becoming a path outside the secrets directory.
- Empty credential values are invalid. Null means explicit absence and is
distinct from an empty string.
- Credential values are written as supplied strings. ConfigKit and the typed
application reference own any nonempty-value requirement when a credential
is selected for use.
- An omitted mapping key is outside the role's ownership. Exact-directory
mirroring and deletion of unlisted files are intentionally excluded.
- The shared runtime group is an authorization group. Its members may read the
@@ -280,8 +278,8 @@ generic and does not own credential files or suite policy.
The pipeline role needs one empty credential mapping, two Narratio Notarius
policy variables, coordinated Audita reference defaults, and ordinary
dependency wiring. Credential convergence consists of one directory task, one
validation loop, one copy loop for non-null entries, and one file loop for
explicit null removals. Both secret-bearing loops suppress their output.
validation loop, and one copy loop for supplied entries. Both secret-bearing
loops suppress their output.
Documentation and focused native integration coverage complete the public
interface. No state probe, handler, template assembly, manifest, wrapper,
@@ -300,9 +298,10 @@ environment-precedence and redaction rules.
A mapping is more ergonomic for inventory than a list of file objects because
the native identity of each entry is already its environment-variable name.
Null provides explicit removal without making an empty mapping destructive or
requiring a filesystem scan. Omitted files remain available for consumers that
combine Ansible-managed credentials with another provisioning mechanism.
Omitted files remain unmanaged so consumers can combine Ansible-managed
credentials with another provisioning mechanism. Credential removal and
directory mirroring remain outside this feature until an operator-facing
lifecycle requirement is expressly selected.
Per-user `0700` directories would follow Narratio's general recommendation but
would require separate keys or an additional invocation convention for every
@@ -327,12 +326,11 @@ application's documented ownership boundary.
- The pipeline role creates `/usr/local/etc/narratio/secrets` with the selected
runtime ownership and suite credential-directory mode.
- `dnd_pipeline_secrets` defaults to an empty mapping and accepts valid
environment names with nonempty string or null values.
- Invalid names and empty non-null values fail before any destination outside
the declared secret directory can be constructed.
- Non-null entries converge to regular files with the selected runtime
ownership and mode `0640`; null entries converge to absence; omitted names
remain unmanaged.
environment names with string values.
- Invalid names and non-string values fail before any destination outside the
declared secret directory can be constructed.
- Supplied entries converge to regular files with the selected runtime
ownership and mode `0640`; omitted names remain unmanaged.
- Credential values are suppressed from Ansible output and never appear in
application YAML, generated examples, native effective-configuration output,
test logs, or committed fixtures.
@@ -350,12 +348,9 @@ application's documented ownership boundary.
variables unset loads credentials through the conventional directory and
succeeds at native offline configuration validation as the service account
and one existing-group-member fixture.
- One representative explicit-null transition makes the selected synthetic
credential unavailable through the native bootstrap boundary without
inspecting module results or file metadata.
- A distinctive synthetic secret never appears in captured integration output.
- The baseline and representative credential applications each report
`changed=0` and `failed=0` on an immediate identical repeat.
- The baseline credential application reports `changed=0` and `failed=0` on
an immediate identical repeat.
- Syntax checking, production-profile lint, and the complete standalone
Narratio and pipeline integration entry points pass.
- No live provider, WhisperX service, storage backend, model call, or
@@ -389,4 +384,6 @@ application's documented ownership boundary.
not treat runtime-group membership as shared credential authorization.
- Add explicit credential rotation orchestration and provider-side validity
checks.
- Add an explicit credential-removal or directory-lifecycle contract if an
operator need is identified.
- Add platform-specific mandatory-access-control policy for credential files.