Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
565
vendor/ruvector/examples/edge-net/docs/security/README.md
vendored
Normal file
565
vendor/ruvector/examples/edge-net/docs/security/README.md
vendored
Normal file
@@ -0,0 +1,565 @@
|
||||
# @ruvector/edge-net Security Review
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document provides a comprehensive security analysis of the edge-net distributed compute network. The system enables browsers to contribute compute power and earn credits, creating a P2P marketplace for AI workloads.
|
||||
|
||||
**Security Classification: HIGH RISK**
|
||||
|
||||
A distributed compute network with financial incentives presents significant attack surface. This review identifies threats, mitigations, and remaining risks.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Threat Model](#1-threat-model)
|
||||
2. [Attack Vectors](#2-attack-vectors)
|
||||
3. [Security Controls](#3-security-controls)
|
||||
4. [QDAG Currency Security](#4-qdag-currency-security)
|
||||
5. [Cryptographic Choices](#5-cryptographic-choices)
|
||||
6. [Remaining Risks](#6-remaining-risks)
|
||||
7. [Security Recommendations](#7-security-recommendations)
|
||||
8. [Incident Response](#8-incident-response)
|
||||
|
||||
---
|
||||
|
||||
## 1. Threat Model
|
||||
|
||||
### 1.1 Assets at Risk
|
||||
|
||||
| Asset | Value | Impact if Compromised |
|
||||
|-------|-------|----------------------|
|
||||
| **User credits** | Financial | Direct monetary loss |
|
||||
| **Task payloads** | Confidential | Data breach, IP theft |
|
||||
| **Compute results** | Integrity | Incorrect AI outputs |
|
||||
| **Node identities** | Reputation | Impersonation, fraud |
|
||||
| **Network state** | Availability | Service disruption |
|
||||
| **QDAG ledger** | Financial | Double-spend, inflation |
|
||||
|
||||
### 1.2 Threat Actors
|
||||
|
||||
| Actor | Capability | Motivation |
|
||||
|-------|------------|------------|
|
||||
| **Script kiddie** | Low | Vandalism, testing |
|
||||
| **Fraudster** | Medium | Credit theft, fake compute |
|
||||
| **Competitor** | Medium-High | Disruption, espionage |
|
||||
| **Nation-state** | Very High | Surveillance, sabotage |
|
||||
| **Insider** | High | Financial gain |
|
||||
|
||||
### 1.3 Trust Boundaries
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ UNTRUSTED ZONE │
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ Malicious │ │ Network │ │ Rogue │ │
|
||||
│ │ Client │ │ Traffic │ │ Worker │ │
|
||||
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
||||
│ │ │ │ │
|
||||
├──────────┼──────────────────────┼──────────────────────┼────────────────┤
|
||||
│ │ TRUST BOUNDARY │ │
|
||||
├──────────┼──────────────────────┼──────────────────────┼────────────────┤
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ EDGE-NET NODE │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
|
||||
│ │ │ Identity │ │ QDAG │ │ Task │ │ Security │ │ │
|
||||
│ │ │ Verify │ │ Verify │ │ Verify │ │ Checks │ │ │
|
||||
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ ┌──────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ WASM SANDBOX (Trusted) │ │ │
|
||||
│ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │
|
||||
│ │ │ │ Compute │ │ Credit │ │ Crypto │ │ │ │
|
||||
│ │ │ │ Execution │ │ Ledger │ │ Engine │ │ │ │
|
||||
│ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │
|
||||
│ │ └──────────────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ TRUSTED ZONE │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Attack Vectors
|
||||
|
||||
### 2.1 Sybil Attacks
|
||||
|
||||
**Threat:** Attacker creates many fake identities to:
|
||||
- Claim disproportionate compute rewards
|
||||
- Manipulate task verification voting
|
||||
- Control consensus outcomes
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// Browser fingerprinting (privacy-preserving)
|
||||
BrowserFingerprint::generate() -> unique hash
|
||||
|
||||
// Stake requirement
|
||||
const MIN_STAKE: u64 = 100_000_000; // 100 credits to participate
|
||||
|
||||
// Rate limiting
|
||||
RateLimiter::check_allowed(node_id) -> bool
|
||||
|
||||
// Sybil defense
|
||||
SybilDefense::register_node(node_id, fingerprint) -> bool (max 3 per fingerprint)
|
||||
```
|
||||
|
||||
**Residual Risk:** MEDIUM
|
||||
- Fingerprinting can be bypassed with VMs/incognito
|
||||
- Stake requirement helps but motivated attackers can acquire credits
|
||||
- Recommendation: Add proof-of-humanity (optional) for high-value operations
|
||||
|
||||
### 2.2 Free-Riding Attacks
|
||||
|
||||
**Threat:** Attacker claims compute rewards without doing real work:
|
||||
- Returns random/garbage results
|
||||
- Copies results from honest workers
|
||||
- Times out intentionally
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// Redundant execution (N workers verify same task)
|
||||
task.redundancy = 3; // 3 workers, majority wins
|
||||
|
||||
// Spot-checking with known answers
|
||||
SpotChecker::should_check() -> 10% of tasks verified
|
||||
SpotChecker::verify_response(input, output) -> bool
|
||||
|
||||
// Execution proofs
|
||||
ExecutionProof {
|
||||
io_hash: hash(input + output),
|
||||
checkpoints: Vec<intermediate_hashes>,
|
||||
}
|
||||
|
||||
// Reputation consequences
|
||||
ReputationSystem::record_penalty(node_id, 0.3); // 30% reputation hit
|
||||
```
|
||||
|
||||
**Residual Risk:** LOW-MEDIUM
|
||||
- Redundancy provides strong protection but costs 3x compute
|
||||
- Spot-checks effective but can be gamed if challenges leak
|
||||
- Recommendation: Implement rotating challenge set, consider ZK proofs
|
||||
|
||||
### 2.3 Double-Spend Attacks (QDAG)
|
||||
|
||||
**Threat:** Attacker spends same credits twice:
|
||||
- Creates conflicting transactions
|
||||
- Exploits network partitions
|
||||
- Manipulates cumulative weight
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// DAG structure prevents linear double-spend
|
||||
tx.validates = vec![parent1, parent2]; // Must reference 2+ existing tx
|
||||
|
||||
// Cumulative weight (similar to confirmation depth)
|
||||
cumulative_weight = sum(parent_weights) + 1;
|
||||
|
||||
// Proof of work (spam prevention)
|
||||
pow_difficulty = 16; // ~65K hashes per tx
|
||||
|
||||
// Cryptographic signatures
|
||||
tx.signature_ed25519 = sign(hash(tx_content));
|
||||
```
|
||||
|
||||
**Residual Risk:** MEDIUM
|
||||
- DAG is more complex than blockchain, edge cases possible
|
||||
- No formal verification of consensus properties
|
||||
- Recommendation: Model with TLA+ or similar, add watchtower nodes
|
||||
|
||||
### 2.4 Task Injection Attacks
|
||||
|
||||
**Threat:** Attacker submits malicious tasks:
|
||||
- Exfiltrate worker data
|
||||
- Execute arbitrary code
|
||||
- Denial of service via resource exhaustion
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// Task type whitelist
|
||||
match task.task_type {
|
||||
TaskType::VectorSearch => ..., // Known, safe operations
|
||||
TaskType::CustomWasm => Err("Requires explicit verification"),
|
||||
}
|
||||
|
||||
// Resource limits
|
||||
WasmTaskExecutor {
|
||||
max_memory: 256 * 1024 * 1024, // 256MB
|
||||
max_time_ms: 30_000, // 30 seconds
|
||||
}
|
||||
|
||||
// Payload encryption (only intended recipient can read)
|
||||
encrypted_payload = encrypt(payload, recipient_pubkey);
|
||||
|
||||
// Signature verification
|
||||
verify_signature(task, submitter_pubkey);
|
||||
```
|
||||
|
||||
**Residual Risk:** LOW
|
||||
- WASM sandbox provides strong isolation
|
||||
- Resource limits prevent DoS
|
||||
- CustomWasm explicitly disabled by default
|
||||
- Recommendation: Add task size limits, implement quota system
|
||||
|
||||
### 2.5 Man-in-the-Middle Attacks
|
||||
|
||||
**Threat:** Attacker intercepts and modifies network traffic:
|
||||
- Steal task payloads
|
||||
- Modify results
|
||||
- Impersonate nodes
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// End-to-end encryption
|
||||
task.encrypted_payload = aes_gcm_encrypt(key, payload);
|
||||
|
||||
// Message authentication
|
||||
signature = ed25519_sign(private_key, message);
|
||||
|
||||
// Node identity verification
|
||||
verify(public_key, message, signature);
|
||||
```
|
||||
|
||||
**Residual Risk:** LOW
|
||||
- E2E encryption prevents content inspection
|
||||
- Signatures prevent modification
|
||||
- Recommendation: Implement certificate pinning for relay connections
|
||||
|
||||
### 2.6 Denial of Service
|
||||
|
||||
**Threat:** Attacker overwhelms network:
|
||||
- Flood with fake tasks
|
||||
- Exhaust relay resources
|
||||
- Target specific nodes
|
||||
|
||||
**Mitigations Implemented:**
|
||||
```rust
|
||||
// Rate limiting
|
||||
RateLimiter {
|
||||
window_ms: 60_000, // 1 minute window
|
||||
max_requests: 100, // 100 requests max
|
||||
}
|
||||
|
||||
// Stake requirement (economic cost to attack)
|
||||
min_stake: 100_000_000
|
||||
|
||||
// PoW for QDAG transactions
|
||||
pow_difficulty: 16 // Computational cost per tx
|
||||
|
||||
// Task expiration
|
||||
expires_at: now + 60_000 // Tasks expire in 1 minute
|
||||
```
|
||||
|
||||
**Residual Risk:** MEDIUM
|
||||
- Distributed nature helps absorb attacks
|
||||
- Relays are still centralized chokepoints
|
||||
- Recommendation: Deploy multiple relay providers, implement circuit breakers
|
||||
|
||||
---
|
||||
|
||||
## 3. Security Controls
|
||||
|
||||
### 3.1 Control Matrix
|
||||
|
||||
| Control | Type | Status | Effectiveness |
|
||||
|---------|------|--------|---------------|
|
||||
| Ed25519 signatures | Cryptographic | Implemented | High |
|
||||
| AES-256-GCM encryption | Cryptographic | Implemented | High |
|
||||
| WASM sandboxing | Isolation | Implemented | High |
|
||||
| Rate limiting | Availability | Implemented | Medium |
|
||||
| Stake requirement | Economic | Implemented | Medium |
|
||||
| Reputation system | Behavioral | Implemented | Medium |
|
||||
| Sybil defense | Identity | Implemented | Low-Medium |
|
||||
| Spot-checking | Verification | Implemented | Medium |
|
||||
| Audit logging | Detection | Implemented | Medium |
|
||||
|
||||
### 3.2 Defense in Depth
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────────┐
|
||||
│ Layer 1: Network (Rate limiting, PoW, Geographic diversity) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 2: Identity (Ed25519, Fingerprinting, Reputation) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 3: Economic (Stake, Credits, Penalties) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 4: Cryptographic (AES-GCM, Signatures, Hashing) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 5: Isolation (WASM sandbox, Resource limits) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 6: Verification (Redundancy, Spot-checks, Proofs) │
|
||||
├─────────────────────────────────────────────────────────────────────────┤
|
||||
│ Layer 7: Detection (Audit logs, Anomaly detection) │
|
||||
└─────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. QDAG Currency Security
|
||||
|
||||
### 4.1 Consensus Properties
|
||||
|
||||
| Property | Status | Notes |
|
||||
|----------|--------|-------|
|
||||
| **Safety** | Partial | DAG prevents simple double-spend, but lacks formal proof |
|
||||
| **Liveness** | Yes | Feeless, always possible to transact |
|
||||
| **Finality** | Probabilistic | Higher weight = more confirmations |
|
||||
| **Censorship resistance** | Yes | No miners/validators to bribe |
|
||||
|
||||
### 4.2 Attack Resistance
|
||||
|
||||
| Attack | Resistance | Mechanism |
|
||||
|--------|------------|-----------|
|
||||
| Double-spend | Medium | Cumulative weight, redundancy |
|
||||
| 51% attack | N/A | No mining, all nodes equal |
|
||||
| Sybil | Medium | Stake + fingerprinting |
|
||||
| Spam | Medium | PoW + rate limiting |
|
||||
| Front-running | Low | Transactions are public |
|
||||
|
||||
### 4.3 Economic Security
|
||||
|
||||
```
|
||||
Attack Cost Analysis:
|
||||
|
||||
Scenario: Attacker wants to double-spend 1000 credits
|
||||
|
||||
1. Stake requirement: 100 credits minimum
|
||||
2. PoW cost: ~65K hashes × transaction fee (0) = ~$0.01 electricity
|
||||
3. Detection probability: ~90% (redundancy + spot-checks)
|
||||
4. Penalty if caught: Stake slashed (100 credits) + reputation damage
|
||||
|
||||
Expected Value:
|
||||
Success (10%): +1000 credits
|
||||
Failure (90%): -100 credits (stake) - reputation
|
||||
|
||||
EV = 0.1 × 1000 - 0.9 × 100 = 100 - 90 = +10 credits
|
||||
|
||||
PROBLEM: Positive expected value for attack!
|
||||
|
||||
Mitigation needed:
|
||||
- Increase stake requirement to 200+ credits
|
||||
- Add delayed finality (1 hour) for large transfers
|
||||
- Require higher redundancy for high-value tasks
|
||||
```
|
||||
|
||||
### 4.4 Recommended Improvements
|
||||
|
||||
1. **Increase minimum stake to 1000 credits** for contributor nodes
|
||||
2. **Implement time-locked withdrawals** (24h delay for large amounts)
|
||||
3. **Add transaction confirmation threshold** (weight > 10 for finality)
|
||||
4. **Watchdog nodes** that monitor for conflicts and alert
|
||||
|
||||
---
|
||||
|
||||
## 5. Cryptographic Choices
|
||||
|
||||
### 5.1 Algorithm Selection
|
||||
|
||||
| Use Case | Algorithm | Key Size | Security Level | Quantum Safe |
|
||||
|----------|-----------|----------|----------------|--------------|
|
||||
| Signatures | Ed25519 | 256-bit | 128-bit | No |
|
||||
| Encryption | AES-256-GCM | 256-bit | 256-bit | Partial |
|
||||
| Hashing | SHA-256 | 256-bit | 128-bit | Partial |
|
||||
| Key exchange | X25519 | 256-bit | 128-bit | No |
|
||||
|
||||
### 5.2 Quantum Resistance Roadmap
|
||||
|
||||
Current implementation is NOT quantum-safe. Mitigation plan:
|
||||
|
||||
**Phase 1 (Current):** Ed25519 + AES-256-GCM
|
||||
- Sufficient for near-term (5-10 years)
|
||||
- Fast and well-tested
|
||||
|
||||
**Phase 2 (Planned):** Hybrid signatures
|
||||
```rust
|
||||
pub struct HybridSignature {
|
||||
ed25519: [u8; 64],
|
||||
dilithium: Option<[u8; 2420]>, // Post-quantum
|
||||
}
|
||||
```
|
||||
|
||||
**Phase 3 (Future):** Full post-quantum
|
||||
- Replace X25519 with CRYSTALS-Kyber
|
||||
- Replace Ed25519 with CRYSTALS-Dilithium
|
||||
- Timeline: When NIST standards are finalized and WASM support available
|
||||
|
||||
### 5.3 Key Management
|
||||
|
||||
| Key Type | Storage | Lifecycle | Rotation |
|
||||
|----------|---------|-----------|----------|
|
||||
| Identity private key | localStorage (encrypted) | Long-term | On compromise only |
|
||||
| Task encryption key | Memory only | Per-task | Every task |
|
||||
| Session key | Memory only | Per-session | Every session |
|
||||
|
||||
**Recommendations:**
|
||||
1. Add option to export/backup identity keys
|
||||
2. Implement key derivation for sub-keys
|
||||
3. Consider hardware security module integration
|
||||
|
||||
---
|
||||
|
||||
## 6. Remaining Risks
|
||||
|
||||
### 6.1 High Priority
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation Status |
|
||||
|------|------------|--------|-------------------|
|
||||
| QDAG double-spend | Medium | High | Partial - needs more stake |
|
||||
| Relay compromise | Medium | High | Not addressed - single point of failure |
|
||||
| Fingerprint bypass | High | Medium | Accepted - layered defense |
|
||||
|
||||
### 6.2 Medium Priority
|
||||
|
||||
| Risk | Likelihood | Impact | Mitigation Status |
|
||||
|------|------------|--------|-------------------|
|
||||
| Quantum computer attack | Low (5+ years) | Critical | Planned - hybrid signatures |
|
||||
| Result manipulation | Medium | Medium | Implemented - redundancy |
|
||||
| Credit inflation | Low | High | Implemented - max supply cap |
|
||||
|
||||
### 6.3 Accepted Risks
|
||||
|
||||
| Risk | Rationale for Acceptance |
|
||||
|------|--------------------------|
|
||||
| Browser fingerprint bypass | Defense in depth, not sole protection |
|
||||
| Front-running | Low value per transaction |
|
||||
| Denial of service on single node | Network is distributed |
|
||||
|
||||
---
|
||||
|
||||
## 7. Security Recommendations
|
||||
|
||||
### 7.1 Immediate (Before Launch)
|
||||
|
||||
1. **Increase minimum stake to 1000 credits**
|
||||
- Current 100 credits allows profitable attacks
|
||||
- Higher stake increases attacker cost
|
||||
|
||||
2. **Add time-locked withdrawals for large amounts**
|
||||
```rust
|
||||
if amount > 10_000 {
|
||||
withdrawal_delay = 24 * 60 * 60 * 1000; // 24 hours
|
||||
}
|
||||
```
|
||||
|
||||
3. **Implement relay redundancy**
|
||||
- Use 3+ relay providers
|
||||
- Implement failover logic
|
||||
- Monitor relay health
|
||||
|
||||
4. **Add anomaly detection**
|
||||
- Monitor for unusual transaction patterns
|
||||
- Alert on reputation drops
|
||||
- Track geographic distribution
|
||||
|
||||
### 7.2 Short-Term (1-3 Months)
|
||||
|
||||
1. **Formal verification of QDAG consensus**
|
||||
- Model in TLA+ or similar
|
||||
- Prove safety properties
|
||||
- Test with chaos engineering
|
||||
|
||||
2. **Bug bounty program**
|
||||
- Engage external security researchers
|
||||
- Reward vulnerability disclosure
|
||||
- Range: $500 - $50,000 based on severity
|
||||
|
||||
3. **Penetration testing**
|
||||
- Engage professional red team
|
||||
- Focus on economic attacks
|
||||
- Test at scale
|
||||
|
||||
### 7.3 Long-Term (3-12 Months)
|
||||
|
||||
1. **Post-quantum cryptography migration**
|
||||
- Implement Dilithium signatures
|
||||
- Implement Kyber key exchange
|
||||
- Maintain backward compatibility
|
||||
|
||||
2. **Hardware security module support**
|
||||
- WebAuthn integration for identity
|
||||
- Secure key storage
|
||||
- Biometric authentication
|
||||
|
||||
3. **Decentralized relay network**
|
||||
- Run relay nodes on-chain
|
||||
- Incentivize relay operators
|
||||
- Eliminate single points of failure
|
||||
|
||||
---
|
||||
|
||||
## 8. Incident Response
|
||||
|
||||
### 8.1 Incident Categories
|
||||
|
||||
| Category | Examples | Response Time |
|
||||
|----------|----------|---------------|
|
||||
| P1 - Critical | Double-spend, key compromise | < 1 hour |
|
||||
| P2 - High | Relay outage, spam attack | < 4 hours |
|
||||
| P3 - Medium | Reputation manipulation, minor bugs | < 24 hours |
|
||||
| P4 - Low | Performance issues, UI bugs | < 1 week |
|
||||
|
||||
### 8.2 Response Procedures
|
||||
|
||||
**P1 - Critical Incident:**
|
||||
1. Pause network (if possible)
|
||||
2. Assess damage scope
|
||||
3. Identify root cause
|
||||
4. Deploy fix
|
||||
5. Restore service
|
||||
6. Post-mortem
|
||||
|
||||
**Contacts:**
|
||||
- Security lead: security@ruvector.dev
|
||||
- Emergency: See internal runbook
|
||||
- Bug bounty: hackerone.com/ruvector (pending)
|
||||
|
||||
### 8.3 Disclosure Policy
|
||||
|
||||
- **Private disclosure preferred** for critical vulnerabilities
|
||||
- **90-day disclosure window** before public release
|
||||
- **Credit and bounty** for responsible disclosure
|
||||
- **CVE assignment** for significant vulnerabilities
|
||||
|
||||
---
|
||||
|
||||
## Appendix A: Security Checklist
|
||||
|
||||
### Pre-Launch
|
||||
|
||||
- [ ] Minimum stake increased to 1000 credits
|
||||
- [ ] Time-locked withdrawals implemented
|
||||
- [ ] Multi-relay support tested
|
||||
- [ ] Rate limits tuned for production
|
||||
- [ ] Audit logs reviewed for gaps
|
||||
- [ ] Key backup/recovery tested
|
||||
- [ ] Incident response tested
|
||||
|
||||
### Post-Launch
|
||||
|
||||
- [ ] Bug bounty active
|
||||
- [ ] Penetration test completed
|
||||
- [ ] Formal verification started
|
||||
- [ ] Monitoring dashboards live
|
||||
- [ ] On-call rotation established
|
||||
|
||||
---
|
||||
|
||||
## Appendix B: References
|
||||
|
||||
1. NIST Post-Quantum Cryptography: https://csrc.nist.gov/Projects/post-quantum-cryptography
|
||||
2. Ed25519 specification: https://ed25519.cr.yp.to/
|
||||
3. AES-GCM: NIST SP 800-38D
|
||||
4. DAG-based consensus: IOTA Tangle, Avalanche
|
||||
5. Sybil attack mitigation: https://dl.acm.org/doi/10.1145/586110.586124
|
||||
|
||||
---
|
||||
|
||||
*This document should be reviewed quarterly and updated after any security incident.*
|
||||
|
||||
*Last reviewed: [DATE]*
|
||||
*Next review: [DATE + 90 days]*
|
||||
Reference in New Issue
Block a user