Enterprise Features: - Hosted mode with remote sync for team pattern aggregation - Community sharing with privacy-preserving anonymization - LLM-based semantic claim extraction with Gemini integration - Pattern learning with promotion to declarative extractors - High-entropy secrets extractor with configurable thresholds - Auth bypass and insecure cookies extractors Module Refactoring: - Split oversized files to comply with 500-line limit - Config split: types/core.rs, types/extractors.rs, types/hosted.rs, etc. - Handlers split: scan.rs, policy.rs, report.rs modules - Extractors split: declarative/, high_entropy_secrets/, insecure_cookies/ - Learning split: store modules with metrics and persistence SDK & Ontology: - stemedb-ontology SDK with fluent builders and StemeDB client - Pharma domain extractors for FDA Orange Book data - Consumer health UAT test infrastructure Code Quality: - Fixed clippy warnings (needless_borrows_for_generic_args) - Added KVStore trait imports where needed - Fixed utoipa path re-exports for OpenAPI docs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
270 lines
7.3 KiB
Bash
Executable File
270 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Enterprise Workflow End-to-End Test
|
|
#
|
|
# This script validates the complete Trust Pack workflow:
|
|
# 1. Security team creates standards and exports as Trust Pack
|
|
# 2. Dev team imports pack and scans code with violations
|
|
# 3. Conflicts appear with full policy source attribution
|
|
#
|
|
# Usage: ./test-enterprise-workflow.sh
|
|
#
|
|
# Exit codes:
|
|
# 0 - All tests pass
|
|
# 1 - Test failure
|
|
#
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
APHORIA_BIN="$PROJECT_ROOT/target/release/aphoria"
|
|
TEST_DIR="/tmp/uat-enterprise-workflow"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Track test results
|
|
TESTS_PASSED=0
|
|
TESTS_FAILED=0
|
|
|
|
pass() {
|
|
echo -e "${GREEN}✓${NC} $1"
|
|
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
}
|
|
|
|
fail() {
|
|
echo -e "${RED}✗${NC} $1"
|
|
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
}
|
|
|
|
info() {
|
|
echo -e "${YELLOW}→${NC} $1"
|
|
}
|
|
|
|
section() {
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "$1"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
}
|
|
|
|
# Build Aphoria if needed
|
|
if [ ! -f "$APHORIA_BIN" ]; then
|
|
info "Building Aphoria (release)..."
|
|
(cd "$PROJECT_ROOT" && cargo build --release --package aphoria)
|
|
fi
|
|
|
|
# Clean up any previous test run
|
|
rm -rf "$TEST_DIR"
|
|
mkdir -p "$TEST_DIR"
|
|
|
|
section "Step 1: Create Security Team Project"
|
|
|
|
SECURITY_DIR="$TEST_DIR/security-team"
|
|
mkdir -p "$SECURITY_DIR"
|
|
cd "$SECURITY_DIR"
|
|
|
|
# Create minimal Cargo.toml for project detection
|
|
cat > Cargo.toml << 'EOF'
|
|
[package]
|
|
name = "security-standards"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
|
|
# Create aphoria.toml
|
|
cat > aphoria.toml << 'EOF'
|
|
[episteme]
|
|
data_dir = ".aphoria/db"
|
|
|
|
[project]
|
|
name = "security-standards"
|
|
EOF
|
|
|
|
# Create minimal src
|
|
mkdir -p src
|
|
echo "fn main() {}" > src/main.rs
|
|
|
|
info "Blessing TLS certificate verification standard..."
|
|
# The extractor emits: code://{path}/tls/cert_verification with predicate=enabled, value=false
|
|
# We bless: code://standard/tls/cert_verification with predicate=enabled, value=true
|
|
# Tail-path key for both: tls/cert_verification::enabled
|
|
"$APHORIA_BIN" bless "code://standard/tls/cert_verification" \
|
|
--predicate enabled --value true \
|
|
--reason "Certificate verification required per OWASP ASVS 9.1.1"
|
|
|
|
info "Blessing TLS minimum version standard..."
|
|
# The extractor emits: code://{path}/tls/min_version with predicate=version, value="deprecated"
|
|
# We bless: code://standard/tls/min_version with predicate=version, value="1.2"
|
|
# Tail-path key for both: tls/min_version::version
|
|
"$APHORIA_BIN" bless "code://standard/tls/min_version" \
|
|
--predicate version --value "1.2" \
|
|
--reason "TLS 1.2 minimum per RFC 8446"
|
|
|
|
pass "Security team: blessed 2 standards"
|
|
|
|
info "Exporting Trust Pack..."
|
|
"$APHORIA_BIN" policy export --name "Security-Standards" --output security-standards-v1.0.pack
|
|
|
|
if [ -f "security-standards-v1.0.pack" ]; then
|
|
pass "Security team: exported pack ($(wc -c < security-standards-v1.0.pack) bytes)"
|
|
else
|
|
fail "Security team: pack export failed"
|
|
exit 1
|
|
fi
|
|
|
|
section "Step 2: Create Dev Team Project with Violations"
|
|
|
|
DEV_DIR="$TEST_DIR/dev-team"
|
|
mkdir -p "$DEV_DIR/config"
|
|
cd "$DEV_DIR"
|
|
|
|
# Create minimal Cargo.toml
|
|
cat > Cargo.toml << 'EOF'
|
|
[package]
|
|
name = "my-service"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
EOF
|
|
|
|
# Create aphoria.toml
|
|
cat > aphoria.toml << 'EOF'
|
|
[episteme]
|
|
data_dir = ".aphoria/db"
|
|
|
|
[project]
|
|
name = "my-service"
|
|
EOF
|
|
|
|
# Create minimal src
|
|
mkdir -p src
|
|
echo "fn main() {}" > src/main.rs
|
|
|
|
# Create YAML config with TLS violations that the extractors will detect
|
|
# Note: Avoid putting patterns in comments as they trigger false positives
|
|
cat > config/tls.yaml << 'EOF'
|
|
# TLS configuration for my-service
|
|
# These settings intentionally violate security standards for testing
|
|
|
|
tls:
|
|
# Deprecated version - should trigger conflict
|
|
min_version: "1.0"
|
|
|
|
# Disabled verification - should trigger conflict
|
|
tls_verify: false
|
|
|
|
# These are fine (modern settings)
|
|
max_version: "1.3"
|
|
cipher_suites:
|
|
- TLS_AES_128_GCM_SHA256
|
|
- TLS_AES_256_GCM_SHA384
|
|
EOF
|
|
|
|
pass "Dev team: created project with TLS violations"
|
|
|
|
section "Step 3: Import Trust Pack and Scan"
|
|
|
|
info "Importing security standards pack..."
|
|
"$APHORIA_BIN" policy import "$SECURITY_DIR/security-standards-v1.0.pack"
|
|
pass "Dev team: imported pack"
|
|
|
|
info "Running scan with persistence..."
|
|
SCAN_OUTPUT=$("$APHORIA_BIN" scan --persist --format json 2>&1)
|
|
echo "$SCAN_OUTPUT" > scan-results.json
|
|
|
|
# Count conflicts (by counting verdict fields which indicate conflict results)
|
|
CONFLICT_COUNT=$(echo "$SCAN_OUTPUT" | grep -c '"verdict"' || echo "0")
|
|
|
|
if [ "$CONFLICT_COUNT" -ge 2 ]; then
|
|
pass "Dev team: scan found $CONFLICT_COUNT conflicts"
|
|
else
|
|
fail "Dev team: expected >=2 conflicts, found $CONFLICT_COUNT"
|
|
echo "Scan output:"
|
|
echo "$SCAN_OUTPUT"
|
|
fi
|
|
|
|
section "Step 4: Verify Policy Source Attribution"
|
|
|
|
# Check JSON output has policy_source fields
|
|
info "Checking JSON output for policy_source..."
|
|
if echo "$SCAN_OUTPUT" | grep -q "policy_source"; then
|
|
pass "JSON output: policy_source field present"
|
|
|
|
# Check for specific fields
|
|
if echo "$SCAN_OUTPUT" | grep -q "pack_name"; then
|
|
pass "JSON output: pack_name present"
|
|
else
|
|
fail "JSON output: pack_name missing"
|
|
fi
|
|
|
|
if echo "$SCAN_OUTPUT" | grep -q "pack_version"; then
|
|
pass "JSON output: pack_version present"
|
|
else
|
|
fail "JSON output: pack_version missing"
|
|
fi
|
|
|
|
if echo "$SCAN_OUTPUT" | grep -q "issuer_hex"; then
|
|
pass "JSON output: issuer_hex present"
|
|
else
|
|
fail "JSON output: issuer_hex missing"
|
|
fi
|
|
else
|
|
fail "JSON output: policy_source field missing"
|
|
fi
|
|
|
|
section "Step 5: Verify Other Output Formats"
|
|
|
|
info "Testing table format..."
|
|
TABLE_OUTPUT=$("$APHORIA_BIN" scan --persist --format table 2>&1)
|
|
echo "$TABLE_OUTPUT" > scan-results.txt
|
|
if echo "$TABLE_OUTPUT" | grep -qi "tls"; then
|
|
pass "Table output: contains TLS conflicts"
|
|
else
|
|
fail "Table output: missing TLS conflicts"
|
|
fi
|
|
|
|
info "Testing markdown format..."
|
|
MD_OUTPUT=$("$APHORIA_BIN" scan --persist --format markdown 2>&1)
|
|
echo "$MD_OUTPUT" > scan-results.md
|
|
if echo "$MD_OUTPUT" | grep -q "#"; then
|
|
pass "Markdown output: valid markdown structure"
|
|
else
|
|
fail "Markdown output: invalid structure"
|
|
fi
|
|
|
|
info "Testing SARIF format..."
|
|
SARIF_OUTPUT=$("$APHORIA_BIN" scan --persist --format sarif 2>&1)
|
|
echo "$SARIF_OUTPUT" > scan-results.sarif
|
|
if echo "$SARIF_OUTPUT" | grep -q '"\$schema"'; then
|
|
pass "SARIF output: valid SARIF structure"
|
|
else
|
|
fail "SARIF output: invalid structure"
|
|
fi
|
|
|
|
section "Summary"
|
|
|
|
echo ""
|
|
echo "Test Results:"
|
|
echo " Passed: $TESTS_PASSED"
|
|
echo " Failed: $TESTS_FAILED"
|
|
echo ""
|
|
echo "Test artifacts saved in: $TEST_DIR"
|
|
echo " - security-team/security-standards-v1.0.pack"
|
|
echo " - dev-team/scan-results.json"
|
|
echo " - dev-team/scan-results.txt"
|
|
echo " - dev-team/scan-results.md"
|
|
echo " - dev-team/scan-results.sarif"
|
|
echo ""
|
|
|
|
if [ "$TESTS_FAILED" -gt 0 ]; then
|
|
echo -e "${RED}FAILED${NC}: $TESTS_FAILED tests failed"
|
|
exit 1
|
|
else
|
|
echo -e "${GREEN}SUCCESS${NC}: All tests passed"
|
|
exit 0
|
|
fi
|