security: contracts + tests for all 5 security modules (87→123 checks)
Some checks failed
Deploy (Gitea) / deploy (push) Failing after 2s
Some checks failed
Deploy (Gitea) / deploy (push) Failing after 2s
This commit is contained in:
@@ -6,8 +6,42 @@
|
||||
* Overview
|
||||
The *Credentials Vault* provides secure in-memory storage for sensitive API keys and session tokens.
|
||||
|
||||
* Architectural Intent
|
||||
|
||||
The Credentials Vault isolates secrets from the rest of the system in
|
||||
a dedicated hash-table. It provides simple get/set primitives with
|
||||
environment-variable fallback for known providers. This is the single
|
||||
place where credentials enter the system — every provider skill routes
|
||||
through here.
|
||||
|
||||
** Contract
|
||||
|
||||
1. (vault-set provider secret &key type): stores secret under
|
||||
~(format nil "~a-~a" provider type)~ in ~*vault-memory*~.
|
||||
2. (vault-get provider &key type): returns the stored secret, or falls
|
||||
back to the appropriate environment variable for known providers
|
||||
(~:openai~, ~:anthropic~, ~:openrouter~, ~:gemini~). Returns NIL
|
||||
if neither exists.
|
||||
3. (vault-get-secret provider): wrapper — calls ~vault-get~ with
|
||||
~:type :secret~.
|
||||
4. (vault-set-secret provider secret): wrapper — calls ~vault-set~
|
||||
with ~:type :secret~.
|
||||
5. Vault isolation: storing a secret for provider A does not affect
|
||||
provider B's entry. Different ~:type~ values produce different keys.
|
||||
|
||||
** Boundaries
|
||||
|
||||
- Does NOT encrypt at rest — that is the session layer's responsibility.
|
||||
- Does NOT validate key format — the provider skill does that.
|
||||
- Does NOT rotate or expire keys — this is a simple store.
|
||||
|
||||
* Implementation
|
||||
|
||||
** Package Context
|
||||
#+begin_src lisp
|
||||
(in-package :passepartout)
|
||||
#+end_src
|
||||
|
||||
** Vault Storage
|
||||
;; REPL-VERIFIED: 2026-05-03T13:00:00
|
||||
#+begin_src lisp
|
||||
@@ -41,7 +75,6 @@ The *Credentials Vault* provides secure in-memory storage for sensitive API keys
|
||||
(let ((key (format nil "~a-~a" provider type)))
|
||||
(setf (gethash key *vault-memory*) secret)))
|
||||
#+end_src
|
||||
#+end_src
|
||||
|
||||
** Secret Wrappers (gateway-messaging)
|
||||
|
||||
@@ -62,11 +95,65 @@ Delegates to the existing =vault-get=/=vault-set= with ~:type :secret~.
|
||||
"Stores a secret or token for a gateway provider."
|
||||
(vault-set provider secret :type :secret))
|
||||
#+end_src
|
||||
#+end_src
|
||||
|
||||
** Skill Registration
|
||||
#+begin_src lisp
|
||||
(defskill :passepartout-security-vault
|
||||
:priority 600
|
||||
:trigger (lambda (ctx) (declare (ignore ctx)) nil))
|
||||
#+end_src
|
||||
|
||||
* Test Suite
|
||||
|
||||
#+begin_src lisp
|
||||
(eval-when (:compile-toplevel :load-toplevel :execute)
|
||||
(ql:quickload :fiveam :silent t))
|
||||
|
||||
(defpackage :passepartout-security-vault-tests
|
||||
(:use :cl :fiveam :passepartout)
|
||||
(:export #:vault-suite))
|
||||
|
||||
(in-package :passepartout-security-vault-tests)
|
||||
|
||||
(def-suite vault-suite :description "Verification of the Credentials Vault")
|
||||
(in-suite vault-suite)
|
||||
|
||||
(test test-vault-round-trip
|
||||
"Contract 1: vault-set stores a value; vault-get retrieves it."
|
||||
(let ((test-key :vault-test-round-trip)
|
||||
(test-secret "secret-abc123"))
|
||||
(vault-set test-key test-secret)
|
||||
(is (string= test-secret (vault-get test-key)))
|
||||
;; Clean up
|
||||
(vault-set test-key nil)))
|
||||
|
||||
(test test-vault-missing-key
|
||||
"Contract 2: vault-get returns NIL for an unset, unknown provider."
|
||||
(is (null (vault-get :nonexistent-provider-xyz))))
|
||||
|
||||
(test test-vault-isolation
|
||||
"Contract 5: storing for provider A does not affect provider B."
|
||||
(vault-set :vault-prov-a "secret-a")
|
||||
(vault-set :vault-prov-b "secret-b")
|
||||
(is (string= "secret-a" (vault-get :vault-prov-a)))
|
||||
(is (string= "secret-b" (vault-get :vault-prov-b)))
|
||||
(vault-set :vault-prov-a nil)
|
||||
(vault-set :vault-prov-b nil))
|
||||
|
||||
(test test-vault-secret-wrappers
|
||||
"Contracts 3,4: vault-get-secret and vault-set-secret use :type :secret."
|
||||
(let ((test-provider :vault-secret-test))
|
||||
(vault-set-secret test-provider "my-token")
|
||||
(is (string= "my-token" (vault-get-secret test-provider)))
|
||||
;; Clean up
|
||||
(vault-set-secret test-provider nil)))
|
||||
|
||||
(test test-vault-type-isolation
|
||||
"Contract 5: different :type values produce different keys."
|
||||
(vault-set :vault-type-test "key-value" :type :api-key)
|
||||
(vault-set :vault-type-test "secret-value" :type :secret)
|
||||
(is (string= "key-value" (vault-get :vault-type-test :type :api-key)))
|
||||
(is (string= "secret-value" (vault-get :vault-type-test :type :secret)))
|
||||
(vault-set :vault-type-test nil :type :api-key)
|
||||
(vault-set :vault-type-test nil :type :secret))
|
||||
#+end_src
|
||||
Reference in New Issue
Block a user