feat(platform): add new services, tools, tests and crews modules
New router intelligence modules (26 files): alert_ingest/store, audit_store, architecture_pressure, backlog_generator/store, cost_analyzer, data_governance, dependency_scanner, drift_analyzer, incident_* (5 files), llm_enrichment, platform_priority_digest, provider_budget, release_check_runner, risk_* (6 files), signature_state_store, sofiia_auto_router, tool_governance New services: - sofiia-console: Dockerfile, adapters/, monitor/nodes/ops/voice modules, launchd, react static - memory-service: integration_endpoints, integrations, voice_endpoints, static UI - aurora-service: full app suite (analysis, job_store, orchestrator, reporting, schemas, subagents) - sofiia-supervisor: new supervisor service - aistalk-bridge-lite: Telegram bridge lite - calendar-service: CalDAV calendar service with reminders - mlx-stt-service / mlx-tts-service: Apple Silicon speech services - binance-bot-monitor: market monitor service - node-worker: STT/TTS memory providers New tools (9): agent_email, browser_tool, contract_tool, observability_tool, oncall_tool, pr_reviewer_tool, repo_tool, safe_code_executor, secure_vault New crews: agromatrix_crew (10 modules: depth_classifier, doc_facts, doc_focus, farm_state, light_reply, llm_factory, memory_manager, proactivity, reflection_engine, session_context, style_adapter, telemetry) Tests: 85+ test files for all new modules Made-with: Cursor
This commit is contained in:
1
tools/secure_vault/tests/__init__.py
Normal file
1
tools/secure_vault/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# Tests
|
||||
104
tools/secure_vault/tests/test_gmail.py
Normal file
104
tools/secure_vault/tests/test_gmail.py
Normal file
@@ -0,0 +1,104 @@
|
||||
"""
|
||||
Test 1: Store and retrieve Gmail credentials
|
||||
|
||||
Demonstrates:
|
||||
- Initialize vault
|
||||
- Store multiple credentials
|
||||
- Retrieve credentials
|
||||
- List credentials
|
||||
- Delete credentials
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
# Use temp vault directory
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = temp_dir
|
||||
os.environ["VAULT_AUDIT_LOG_DIR"] = temp_dir
|
||||
|
||||
from secure_vault import SecureVault
|
||||
|
||||
|
||||
def test_gmail_credentials():
|
||||
"""Test storing Gmail credentials"""
|
||||
|
||||
print("=== Test: Gmail Credentials ===\n")
|
||||
|
||||
# Initialize vault
|
||||
print("1. Initializing vault...")
|
||||
vault = SecureVault()
|
||||
result = vault.init_vault("my-secure-master-password")
|
||||
print(f" Vault initialized: {result['status']}")
|
||||
|
||||
# Store Gmail credentials
|
||||
print("\n2. Storing Gmail credentials...")
|
||||
|
||||
vault.store(
|
||||
agent_id="sofiia",
|
||||
service="gmail",
|
||||
credential_name="password",
|
||||
value="your-gmail-password"
|
||||
)
|
||||
print(" - Stored password")
|
||||
|
||||
vault.store(
|
||||
agent_id="sofiia",
|
||||
service="gmail",
|
||||
credential_name="oauth_token",
|
||||
value={"access_token": "ya29.xxxx", "refresh_token": "1//xxx"}
|
||||
)
|
||||
print(" - Stored OAuth token")
|
||||
|
||||
vault.store(
|
||||
agent_id="sofiia",
|
||||
service="gmail",
|
||||
credential_name="app_password",
|
||||
value="xxxx xxxx xxxx xxxx",
|
||||
ttl_seconds=3600 # 1 hour
|
||||
)
|
||||
print(" - Stored app password (TTL: 1 hour)")
|
||||
|
||||
# List services
|
||||
print("\n3. Listing services...")
|
||||
services = vault.list("sofiia")
|
||||
print(f" Services: {services}")
|
||||
|
||||
# List credentials
|
||||
print("\n4. Listing credentials for gmail...")
|
||||
creds = vault.list("sofiia", "gmail")
|
||||
print(f" Credentials: {creds}")
|
||||
|
||||
# Retrieve password
|
||||
print("\n5. Retrieving password...")
|
||||
password = vault.get("sofiia", "gmail", "password")
|
||||
print(f" Password retrieved: {password is not None}")
|
||||
|
||||
# Retrieve OAuth token
|
||||
print("\n6. Retrieving OAuth token...")
|
||||
token = vault.get("sofiia", "gmail", "oauth_token")
|
||||
print(f" Token type: {type(token)}")
|
||||
print(f" Has access_token: {'access_token' in token}")
|
||||
|
||||
# Delete credential
|
||||
print("\n7. Deleting app_password...")
|
||||
result = vault.delete("sofiia", "gmail", "app_password")
|
||||
print(f" Status: {result['status']}")
|
||||
|
||||
# Verify deletion
|
||||
creds = vault.list("sofiia", "gmail")
|
||||
print(f" Remaining: {creds}")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
print("\n✅ Gmail credentials test passed!")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_gmail_credentials()
|
||||
194
tools/secure_vault/tests/test_isolation.py
Normal file
194
tools/secure_vault/tests/test_isolation.py
Normal file
@@ -0,0 +1,194 @@
|
||||
"""
|
||||
Test 3: Per-agent isolation
|
||||
|
||||
Demonstrates:
|
||||
- Multiple agents with isolated vaults
|
||||
- Agent-specific access
|
||||
- Export/import between agents
|
||||
- Service-level isolation
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = temp_dir
|
||||
os.environ["VAULT_AUDIT_LOG_DIR"] = temp_dir
|
||||
|
||||
from secure_vault import SecureVault
|
||||
|
||||
|
||||
def test_agent_isolation():
|
||||
"""Test per-agent credential isolation"""
|
||||
|
||||
print("=== Test: Per-Agent Isolation ===\n")
|
||||
|
||||
vault = SecureVault()
|
||||
vault.init_vault("master-password")
|
||||
|
||||
# Create credentials for different agents
|
||||
print("1. Creating credentials for different agents...")
|
||||
|
||||
# Sofiia's credentials
|
||||
vault.store("sofiia", "gmail", "password", "sofiia-gmail-pass")
|
||||
vault.store("sofiia", "github", "token", "sofiia-gh-token")
|
||||
|
||||
# Helion's credentials
|
||||
vault.store("helion", "gmail", "password", "helion-gmail-pass")
|
||||
vault.store("helion", "aws", "access_key", "helion-aws-key")
|
||||
|
||||
# Druid's credentials
|
||||
vault.store("druid", "slack", "webhook", "druid-slack-url")
|
||||
|
||||
print(" - Sofiia: gmail, github")
|
||||
print(" - Helion: gmail, aws")
|
||||
print(" - Druid: slack")
|
||||
|
||||
# List for each agent
|
||||
print("\n2. Listing services per agent...")
|
||||
print(f" Sofiia: {vault.list('sofiia')}")
|
||||
print(f" Helion: {vault.list('helion')}")
|
||||
print(f" Druid: {vault.list('druid')}")
|
||||
|
||||
# Verify isolation - can't access other agent's creds
|
||||
print("\n3. Verifying isolation...")
|
||||
|
||||
# Sofiia tries to access Helion's AWS
|
||||
helion_aws = vault.get("sofiia", "helion", "access_key")
|
||||
print(f" Sofiia accessing Helion's AWS: {helion_aws} (should be None)")
|
||||
|
||||
# But can access own
|
||||
sofiia_gh = vault.get("sofiia", "github", "token")
|
||||
print(f" Sofiia accessing own GitHub: {sofiia_gh}")
|
||||
|
||||
# Helion tries to access Sofiia's Gmail
|
||||
sofiia_gmail = vault.get("helion", "gmail", "password")
|
||||
print(f" Helion accessing Sofiia's Gmail: {sofiia_gmail} (should be None)")
|
||||
|
||||
# Helion can access own
|
||||
helion_aws = vault.get("helion", "aws", "access_key")
|
||||
print(f" Helion accessing own AWS: {helion_aws}")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
print("\n✅ Agent isolation test passed!")
|
||||
return True
|
||||
|
||||
|
||||
def test_export_import():
|
||||
"""Test export/import for P2P"""
|
||||
|
||||
print("\n=== Test: Export/Import ===\n")
|
||||
|
||||
# Source vault
|
||||
print("1. Creating source vault...")
|
||||
source_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = source_dir
|
||||
|
||||
vault = SecureVault()
|
||||
vault.init_vault("source-password")
|
||||
|
||||
vault.store("agent1", "service1", "cred1", "value1")
|
||||
vault.store("agent1", "service1", "cred2", "value2")
|
||||
vault.store("agent1", "service2", "api_key", "secret-api-key")
|
||||
print(" - Stored 3 credentials")
|
||||
|
||||
# Export for agent
|
||||
print("\n2. Exporting agent vault...")
|
||||
export = vault.export_for_agent("agent1")
|
||||
print(f" Exported services: {export['services']}")
|
||||
print(f" Export key provided: {len(export['export_key'])} chars")
|
||||
|
||||
# Clean up source
|
||||
shutil.rmtree(source_dir)
|
||||
|
||||
# Import into new vault
|
||||
print("\n3. Importing into new vault...")
|
||||
target_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = target_dir
|
||||
|
||||
vault2 = SecureVault()
|
||||
vault2.init_vault("target-password")
|
||||
|
||||
result = vault2.import_for_agent(
|
||||
encrypted_vault=export["encrypted_vault"],
|
||||
export_key=export["export_key"],
|
||||
agent_id="agent1"
|
||||
)
|
||||
print(f" Import status: {result['status']}")
|
||||
print(f" Services imported: {result['services_imported']}")
|
||||
|
||||
# Verify import
|
||||
print("\n4. Verifying imported credentials...")
|
||||
creds = vault2.list("agent1")
|
||||
print(f" Services: {creds}")
|
||||
|
||||
val1 = vault2.get("agent1", "service1", "cred1")
|
||||
print(f" cred1: {val1}")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(target_dir)
|
||||
|
||||
print("\n✅ Export/Import test passed!")
|
||||
return True
|
||||
|
||||
|
||||
def test_service_isolation():
|
||||
"""Test service-level isolation within same agent"""
|
||||
|
||||
print("\n=== Test: Service-Level Isolation ===\n")
|
||||
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = temp_dir
|
||||
|
||||
vault = SecureVault()
|
||||
vault.init_vault("password")
|
||||
|
||||
# Store multiple services for same agent
|
||||
vault.store("sofiia", "gmail", "password", "gmail-pass")
|
||||
vault.store("sofiia", "github", "token", "github-token")
|
||||
vault.store("sofiia", "aws", "access_key", "aws-key")
|
||||
vault.store("sofiia", "aws", "secret_key", "aws-secret")
|
||||
|
||||
print("1. Stored credentials for 3 services")
|
||||
|
||||
# List all services
|
||||
services = vault.list("sofiia")
|
||||
print(f"\n2. All services: {services}")
|
||||
|
||||
# List credentials per service
|
||||
print("\n3. Credentials per service:")
|
||||
for svc in services:
|
||||
creds = vault.list("sofiia", svc)
|
||||
print(f" {svc}: {creds}")
|
||||
|
||||
# Delete only AWS credentials
|
||||
print("\n4. Deleting AWS service...")
|
||||
vault.delete("sofiia", "aws", "access_key")
|
||||
vault.delete("sofiia", "aws", "secret_key")
|
||||
|
||||
# Verify other services intact
|
||||
remaining = vault.list("sofiia")
|
||||
print(f"\n5. Remaining services: {remaining}")
|
||||
|
||||
gmail = vault.get("sofiia", "gmail", "password")
|
||||
github = vault.get("sofiia", "github", "token")
|
||||
print(f" Gmail: {gmail}")
|
||||
print(f" GitHub: {github}")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
print("\n✅ Service isolation test passed!")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_agent_isolation()
|
||||
test_export_import()
|
||||
test_service_isolation()
|
||||
118
tools/secure_vault/tests/test_rotate.py
Normal file
118
tools/secure_vault/tests/test_rotate.py
Normal file
@@ -0,0 +1,118 @@
|
||||
"""
|
||||
Test 2: Master key rotation
|
||||
|
||||
Demonstrates:
|
||||
- Store credentials with old key
|
||||
- Rotate to new master key
|
||||
- Verify credentials still accessible
|
||||
- Check key version
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
os.environ["VAULT_DIR"] = temp_dir
|
||||
os.environ["VAULT_AUDIT_LOG_DIR"] = temp_dir
|
||||
|
||||
from secure_vault import SecureVault
|
||||
|
||||
|
||||
def test_key_rotation():
|
||||
"""Test master key rotation"""
|
||||
|
||||
print("=== Test: Master Key Rotation ===\n")
|
||||
|
||||
# Initialize vault with first key
|
||||
print("1. Initializing vault with key v1...")
|
||||
vault = SecureVault()
|
||||
vault.init_vault("old-master-password")
|
||||
|
||||
# Store some credentials
|
||||
print("\n2. Storing credentials with old key...")
|
||||
vault.store("sofiia", "aws", "access_key", "AKIAIOSFODNN7EXAMPLE")
|
||||
vault.store("sofiia", "aws", "secret_key", "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY")
|
||||
vault.store("sofiia", "github", "token", "ghp_xxxxxxxxxxxx")
|
||||
print(" - Stored AWS and GitHub credentials")
|
||||
|
||||
# Check key version
|
||||
print("\n3. Checking key version...")
|
||||
meta_file = os.path.join(temp_dir, ".vault_master.key.meta")
|
||||
with open(meta_file) as f:
|
||||
meta = eval(f.read())
|
||||
print(f" Key version: {meta['key_version']}")
|
||||
|
||||
# Rotate to new key
|
||||
print("\n4. Rotating to new master key...")
|
||||
result = vault.rotate_master_key("new-master-password")
|
||||
print(f" Status: {result['status']}")
|
||||
print(f" New version: {result['key_version']}")
|
||||
print(f" Re-encrypted: {result['credentials_reencrypted']} creds")
|
||||
|
||||
# Verify credentials still accessible
|
||||
print("\n5. Verifying credentials after rotation...")
|
||||
aws_key = vault.get("sofiia", "aws", "access_key")
|
||||
print(f" AWS access key: {aws_key[:10]}...")
|
||||
|
||||
github_token = vault.get("sofiia", "github", "token")
|
||||
print(f" GitHub token: {github_token}")
|
||||
|
||||
# Check new key metadata
|
||||
print("\n6. Checking new key metadata...")
|
||||
with open(meta_file) as f:
|
||||
meta = eval(f.read())
|
||||
print(f" New key version: {meta['key_version']}")
|
||||
print(f" Rotation due: {meta['rotation_due'][:10]}...")
|
||||
|
||||
# List all services
|
||||
print("\n7. Listing all services...")
|
||||
services = vault.list("sofiia")
|
||||
print(f" Services: {services}")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
print("\n✅ Key rotation test passed!")
|
||||
return True
|
||||
|
||||
|
||||
def test_check_expiring():
|
||||
"""Test expiring credentials"""
|
||||
|
||||
print("\n=== Test: Expiring Credentials ===\n")
|
||||
|
||||
vault = SecureVault()
|
||||
vault.init_vault("test-password")
|
||||
|
||||
# Store with short TTL
|
||||
print("1. Storing credentials with TTL...")
|
||||
vault.store("sofiia", "test", "temp_token", "abc123", ttl_seconds=1)
|
||||
print(" - Stored token with 1 second TTL")
|
||||
|
||||
# Check immediately
|
||||
print("\n2. Checking before expiry...")
|
||||
token = vault.get("sofiia", "test", "temp_token")
|
||||
print(f" Token found: {token is not None}")
|
||||
|
||||
# Wait for expiry
|
||||
print("\n3. Waiting for expiry...")
|
||||
import time
|
||||
time.sleep(2)
|
||||
|
||||
# Check after expiry
|
||||
print("\n4. Checking after expiry...")
|
||||
token = vault.get("sofiia", "test", "temp_token")
|
||||
print(f" Token found: {token is not None} (should be False)")
|
||||
|
||||
# Clean up
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
print("\n✅ Expiring credentials test passed!")
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_key_rotation()
|
||||
test_check_expiring()
|
||||
Reference in New Issue
Block a user