From 58259cb9d307494391a0ef085f2723bf1a3eeadd Mon Sep 17 00:00:00 2001 From: salvacybersec Date: Sun, 5 Apr 2026 00:04:42 +0300 Subject: [PATCH] feat(01-01): create main.go, test scaffolding, and testdata fixtures - main.go entry point (7 lines) delegates to cmd.Execute() - cmd/root.go stub so go build ./... compiles (Plan 05 replaces) - pkg/providers, pkg/storage, pkg/engine package stubs - Test stubs with t.Skip() for providers, storage, engine packages - testdata/samples: openai_key.txt, anthropic_key.txt, multiple_keys.txt, no_keys.txt - go build ./... and go test ./... -short both exit 0 --- cmd/root.go | 8 ++++++++ main.go | 7 +++++++ pkg/engine/engine.go | 3 +++ pkg/engine/scanner_test.go | 23 +++++++++++++++++++++++ pkg/providers/providers.go | 3 +++ pkg/providers/registry_test.go | 23 +++++++++++++++++++++++ pkg/storage/db_test.go | 23 +++++++++++++++++++++++ pkg/storage/storage.go | 3 +++ testdata/samples/anthropic_key.txt | 2 ++ testdata/samples/multiple_keys.txt | 3 +++ testdata/samples/no_keys.txt | 3 +++ testdata/samples/openai_key.txt | 2 ++ 12 files changed, 103 insertions(+) create mode 100644 cmd/root.go create mode 100644 main.go create mode 100644 pkg/engine/engine.go create mode 100644 pkg/engine/scanner_test.go create mode 100644 pkg/providers/providers.go create mode 100644 pkg/providers/registry_test.go create mode 100644 pkg/storage/db_test.go create mode 100644 pkg/storage/storage.go create mode 100644 testdata/samples/anthropic_key.txt create mode 100644 testdata/samples/multiple_keys.txt create mode 100644 testdata/samples/no_keys.txt create mode 100644 testdata/samples/openai_key.txt diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..0a22153 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,8 @@ +package cmd + +import "os" + +// Execute is a stub. The real command tree is built in Plan 05. +func Execute() { + _ = os.Args +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..436cb62 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/salvacybersec/keyhunter/cmd" + +func main() { + cmd.Execute() +} diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go new file mode 100644 index 0000000..fd97764 --- /dev/null +++ b/pkg/engine/engine.go @@ -0,0 +1,3 @@ +// Package engine implements the core scanning pipeline. +// Scanner stages (keyword pre-filter, regex matching, entropy analysis) are implemented in Plan 04. +package engine diff --git a/pkg/engine/scanner_test.go b/pkg/engine/scanner_test.go new file mode 100644 index 0000000..c057fd7 --- /dev/null +++ b/pkg/engine/scanner_test.go @@ -0,0 +1,23 @@ +package engine_test + +import ( + "testing" +) + +// TestShannonEntropy verifies the entropy function returns expected values. +// Stub: will be implemented when entropy.go exists (Plan 04). +func TestShannonEntropy(t *testing.T) { + t.Skip("stub — implement after entropy.go exists") +} + +// TestKeywordPreFilter verifies Aho-Corasick pre-filter rejects files without keywords. +// Stub: will be implemented when filter.go exists (Plan 04). +func TestKeywordPreFilter(t *testing.T) { + t.Skip("stub — implement after filter.go exists") +} + +// TestScannerPipeline verifies end-to-end scan of testdata returns expected findings. +// Stub: will be implemented when engine.go exists (Plan 04). +func TestScannerPipeline(t *testing.T) { + t.Skip("stub — implement after engine.go exists") +} diff --git a/pkg/providers/providers.go b/pkg/providers/providers.go new file mode 100644 index 0000000..8f2caa6 --- /dev/null +++ b/pkg/providers/providers.go @@ -0,0 +1,3 @@ +// Package providers handles loading and managing API key provider definitions. +// Provider YAML files are loaded from the embedded filesystem (Plan 02). +package providers diff --git a/pkg/providers/registry_test.go b/pkg/providers/registry_test.go new file mode 100644 index 0000000..8655e4e --- /dev/null +++ b/pkg/providers/registry_test.go @@ -0,0 +1,23 @@ +package providers_test + +import ( + "testing" +) + +// TestRegistryLoad verifies that provider YAML files are loaded from embed.FS. +// Stub: will be implemented when registry.go exists (Plan 02). +func TestRegistryLoad(t *testing.T) { + t.Skip("stub — implement after registry.go exists") +} + +// TestProviderSchemaValidation verifies format_version and last_verified are required. +// Stub: will be implemented when schema.go validation exists (Plan 02). +func TestProviderSchemaValidation(t *testing.T) { + t.Skip("stub — implement after schema.go validation exists") +} + +// TestAhoCorasickBuild verifies Aho-Corasick automaton builds from provider keywords. +// Stub: will be implemented when registry builds automaton (Plan 02). +func TestAhoCorasickBuild(t *testing.T) { + t.Skip("stub — implement after registry AC build exists") +} diff --git a/pkg/storage/db_test.go b/pkg/storage/db_test.go new file mode 100644 index 0000000..88259dd --- /dev/null +++ b/pkg/storage/db_test.go @@ -0,0 +1,23 @@ +package storage_test + +import ( + "testing" +) + +// TestDBOpen verifies SQLite database opens and creates schema. +// Stub: will be implemented when db.go exists (Plan 03). +func TestDBOpen(t *testing.T) { + t.Skip("stub — implement after db.go exists") +} + +// TestEncryptDecryptRoundtrip verifies AES-256-GCM encrypt/decrypt roundtrip. +// Stub: will be implemented when encrypt.go exists (Plan 03). +func TestEncryptDecryptRoundtrip(t *testing.T) { + t.Skip("stub — implement after encrypt.go exists") +} + +// TestArgon2KeyDerivation verifies Argon2id produces 32-byte key deterministically. +// Stub: will be implemented when crypto.go exists (Plan 03). +func TestArgon2KeyDerivation(t *testing.T) { + t.Skip("stub — implement after crypto.go exists") +} diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go new file mode 100644 index 0000000..c1e0953 --- /dev/null +++ b/pkg/storage/storage.go @@ -0,0 +1,3 @@ +// Package storage handles SQLite database operations with AES-256 encryption. +// Database schema and encryption are implemented in Plan 03. +package storage diff --git a/testdata/samples/anthropic_key.txt b/testdata/samples/anthropic_key.txt new file mode 100644 index 0000000..6b0f1d5 --- /dev/null +++ b/testdata/samples/anthropic_key.txt @@ -0,0 +1,2 @@ +# Test file: synthetic Anthropic key pattern +export ANTHROPIC_API_KEY="sk-ant-api03-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy01234567890-ABCDE" diff --git a/testdata/samples/multiple_keys.txt b/testdata/samples/multiple_keys.txt new file mode 100644 index 0000000..63b1388 --- /dev/null +++ b/testdata/samples/multiple_keys.txt @@ -0,0 +1,3 @@ +# Multiple providers in one file +OPENAI_API_KEY=sk-proj-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr5678 +ANTHROPIC_API_KEY=sk-ant-api03-XYZabcdefghijklmnopqrstuvwxyz01234567890ABCDEFGH-XYZAB diff --git a/testdata/samples/no_keys.txt b/testdata/samples/no_keys.txt new file mode 100644 index 0000000..0337ca9 --- /dev/null +++ b/testdata/samples/no_keys.txt @@ -0,0 +1,3 @@ +# This file contains no API keys +# Used to verify false-positive rate is zero for clean files +Hello world diff --git a/testdata/samples/openai_key.txt b/testdata/samples/openai_key.txt new file mode 100644 index 0000000..0d4a240 --- /dev/null +++ b/testdata/samples/openai_key.txt @@ -0,0 +1,2 @@ +# Test file: synthetic OpenAI key pattern +OPENAI_API_KEY=sk-proj-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr1234