Resolve typed credentials safely
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -8,6 +9,8 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
func TestRepresentativeLoadDefaultsAndValidation(t *testing.T) {
|
||||
@@ -83,6 +86,78 @@ whisperx:
|
||||
}
|
||||
}
|
||||
|
||||
func TestCredentialValuesNeverEnterEffectiveProjectionOrDigest(t *testing.T) {
|
||||
const firstCanary = "credential-canary-first"
|
||||
const secondCanary = "credential-canary-second"
|
||||
t.Setenv("NARRATIO_TEST_ACCESS_KEY", firstCanary)
|
||||
t.Setenv("NARRATIO_TEST_SECRET_KEY", firstCanary)
|
||||
t.Setenv("NARRATIO_TEST_AUDITA_KEY", firstCanary)
|
||||
pipelineYAML := strings.Replace(testPipelineBaseYAML, "audita:\n binary: audita\n", "audita:\n binary: audita\n llm_api_key: NARRATIO_TEST_AUDITA_KEY\n", 1) + `
|
||||
storage:
|
||||
backend: s3
|
||||
s3:
|
||||
bucket: test-bucket
|
||||
access_key_id: NARRATIO_TEST_ACCESS_KEY
|
||||
secret_access_key: NARRATIO_TEST_SECRET_KEY
|
||||
`
|
||||
pipelinePath, _ := writeConfigFiles(t, pipelineYAML, testSessionBaseYAML)
|
||||
|
||||
first, err := LoadPipeline(pipelinePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
firstYAML, err := MarshalEffectivePipeline(first)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
firstValues, err := EffectivePipelineValues(first)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
serializedValues := ""
|
||||
for _, value := range firstValues {
|
||||
serializedValues += value.Path + "=" + value.Value + "\n"
|
||||
}
|
||||
directYAML, err := yaml.Marshal(first)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
directJSON, err := json.Marshal(first)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, output := range []string{string(firstYAML), serializedValues, string(directYAML), string(directJSON)} {
|
||||
if strings.Contains(output, firstCanary) {
|
||||
t.Fatalf("effective output exposed credential value: %q", output)
|
||||
}
|
||||
for _, reference := range []string{"NARRATIO_TEST_ACCESS_KEY", "NARRATIO_TEST_SECRET_KEY", "NARRATIO_TEST_AUDITA_KEY"} {
|
||||
if !strings.Contains(output, reference) {
|
||||
t.Fatalf("effective output omitted safe reference %q: %q", reference, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t.Setenv("NARRATIO_TEST_ACCESS_KEY", secondCanary)
|
||||
t.Setenv("NARRATIO_TEST_SECRET_KEY", secondCanary)
|
||||
t.Setenv("NARRATIO_TEST_AUDITA_KEY", secondCanary)
|
||||
second, err := LoadPipeline(pipelinePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if EffectivePipelineDigest(first) != EffectivePipelineDigest(second) {
|
||||
t.Fatal("credential value change altered effective digest")
|
||||
}
|
||||
t.Setenv("NARRATIO_TEST_AUDITA_KEY_ALTERNATE", secondCanary)
|
||||
alternatePath, _ := writeConfigFiles(t, strings.Replace(pipelineYAML, "NARRATIO_TEST_AUDITA_KEY", "NARRATIO_TEST_AUDITA_KEY_ALTERNATE", 1), testSessionBaseYAML)
|
||||
alternate, err := LoadPipeline(alternatePath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if EffectivePipelineDigest(first) == EffectivePipelineDigest(alternate) {
|
||||
t.Fatal("credential reference-name change did not alter effective digest")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEffectivePipelineValuesPreserveNilEmptyAndExactIntegers(t *testing.T) {
|
||||
base := &PipelineConfig{Audita: AuditaConfig{Modules: nil}}
|
||||
nilValues, err := EffectivePipelineValues(base)
|
||||
@@ -106,6 +181,13 @@ func TestEffectivePipelineValuesPreserveNilEmptyAndExactIntegers(t *testing.T) {
|
||||
if got := effectiveValueForTest(t, emptyValues, "scriptorium.artifacts.recap.vars.exact"); got != "9007199254740993" {
|
||||
t.Fatalf("exact integer value = %q", got)
|
||||
}
|
||||
encoded, err := MarshalEffectivePipeline(base)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !strings.Contains(string(encoded), "9007199254740993") {
|
||||
t.Fatalf("effective YAML lost exact integer: %q", encoded)
|
||||
}
|
||||
}
|
||||
|
||||
func effectiveValueForTest(t *testing.T, values []EffectivePipelineValueRecord, path string) string {
|
||||
@@ -138,6 +220,9 @@ func TestValidateMissingAudioSource(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestExamplesLoadAndValidate(t *testing.T) {
|
||||
t.Setenv("OBJECT_STORAGE_KEY_ID", "synthetic-example-access-key")
|
||||
t.Setenv("OBJECT_STORAGE_KEY", "synthetic-example-secret-key")
|
||||
t.Setenv("AUDITA_LLM_API_KEY", "synthetic-example-audita-key")
|
||||
examplesDir := filepath.Join("..", "..", "examples")
|
||||
if got, want := maintainedPipelineRoots(t, examplesDir), []string{
|
||||
"pipeline.extraction-subset.yml",
|
||||
@@ -226,7 +311,7 @@ func TestExamplesLoadAndValidate(t *testing.T) {
|
||||
if cfg.Pipeline.Audita.Model != profile.model {
|
||||
t.Fatalf("audita model = %q, want %q", cfg.Pipeline.Audita.Model, profile.model)
|
||||
}
|
||||
if cfg.Pipeline.Audita.LLMAPIKeyEnv != "" || cfg.Pipeline.Storage.Backend != StorageBackendLocal || cfg.Pipeline.Storage.S3 != nil {
|
||||
if cfg.Pipeline.Audita.LLMAPIKey != nil || cfg.Pipeline.Storage.Backend != StorageBackendLocal || cfg.Pipeline.Storage.S3 != nil {
|
||||
t.Fatalf("split bundle must remain offline and secret-free: audita=%#v storage=%#v", cfg.Pipeline.Audita, cfg.Pipeline.Storage)
|
||||
}
|
||||
if selectedProfile, ok := SelectedPipelineProfile(cfg.Pipeline); !ok || selectedProfile.Name != profile.name {
|
||||
@@ -295,6 +380,9 @@ func maintainedPipelineRoots(t *testing.T, examplesDir string) []string {
|
||||
}
|
||||
|
||||
func TestMaintainedExtractionExamplesPreservePublishedContracts(t *testing.T) {
|
||||
t.Setenv("OBJECT_STORAGE_KEY_ID", "synthetic-example-access-key")
|
||||
t.Setenv("OBJECT_STORAGE_KEY", "synthetic-example-secret-key")
|
||||
t.Setenv("AUDITA_LLM_API_KEY", "synthetic-example-audita-key")
|
||||
examplesDir := filepath.Join("..", "..", "examples")
|
||||
full, err := LoadPipeline(filepath.Join(examplesDir, "pipeline.full.annotated.yml"))
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user