Fail-Secure Behaviors
Overview
ASCEND implements fail-secure (also known as fail-closed or fail-safe) behavior across all 12 security layers. When any security component fails, encounters an error, or becomes unavailable, the system defaults to the most secure state: DENY.
This approach ensures that security is maintained even during infrastructure failures, misconfigurations, or attack attempts that might try to exploit error conditions.
Why It Matters
Fail-secure design is critical for enterprise security because:
- Attack Mitigation: Attackers often attempt to trigger errors to bypass security controls
- Compliance Requirements: SOC 2, HIPAA, and PCI-DSS require systems to fail in a secure manner
- Defense in Depth: Ensures protection even when individual components fail
- Trust Maintenance: Customers can trust that their data remains protected during outages
The alternative approach, "fail-open," would allow requests through when security controls fail - creating potential security gaps during the most vulnerable moments.
Architecture
Fail-Secure Decision Flow
+------------------+
| Security Check |
+--------+---------+
|
+----+----+
| |
v v
+-------+ +-------+
| PASS | | FAIL |
+---+---+ +---+---+
| |
| +-----+-----+
| | |
v v v
+------+ +--------+ +---------+
| ALLOW| | ERROR | | TIMEOUT |
+------+ +---+----+ +----+----+
| |
+------+-----+
|
v
+------+------+
| DENY |
| (Fail-Secure)|
+-------------+
Layer-by-Layer Fail-Secure Behavior
Layer 1: Rate Limiting
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Redis unavailable | DENY all rate-limited requests | Prevents abuse during outage |
| Rate limit config missing | Apply strictest default (5/min) | Assumes sensitive endpoint |
| Counter update fails | DENY and log error | Prevents counter bypass |
| IP geolocation fails | Apply global limits | No geographic exemptions |
Error Response:
{
"error": "service_unavailable",
"message": "Rate limiting service temporarily unavailable",
"retry_after": 60
}
Layer 2: Prompt Security
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Pattern loading fails | BLOCK all prompts | Assumes all prompts potentially malicious |
| Pattern matching timeout | BLOCK prompt | Prevents timeout-based bypass |
| Encoding detection fails | BLOCK prompt | Assumes encoded attack |
| Database config unavailable | Use strictest defaults | Enforces maximum protection |
Error Response:
{
"error": "prompt_security_error",
"message": "Prompt security analysis failed - request blocked",
"blocked": true,
"reason": "fail_secure"
}
Layer 3: Code Analysis
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Pattern loading fails | BLOCK all code execution | Assumes code is dangerous |
| Analysis timeout | BLOCK code | Prevents complexity-based bypass |
| Language detection fails | Analyze as "any" language | Applies all patterns |
| Config unavailable | Use strictest mode | Maximum protection |
Error Response:
{
"error": "code_analysis_error",
"message": "Code analysis failed - execution blocked",
"blocked": true,
"reason": "fail_secure"
}
Layer 4: Action Governance
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Policy engine unavailable | DENY all actions | No unchecked actions |
| Risk scoring fails | Assign maximum risk (100) | Assumes worst case |
| Smart rules unavailable | DENY pending review | Requires human approval |
| Kill switch state unknown | Assume BLOCKED | Safest assumption |
Error Response:
{
"error": "governance_error",
"message": "Action governance check failed - action denied",
"decision": "DENY",
"reason": "fail_secure"
}
Layer 5: JWT Authentication
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| JWKS fetch fails | DENY authentication | No signature validation possible |
| Public key not found | DENY authentication | Cannot verify token |
| Signature verification error | DENY authentication | Token may be tampered |
| Claims validation error | DENY authentication | Token may be invalid |
| Token revocation check fails | DENY authentication | Cannot confirm token validity |
| Cognito unavailable | DENY authentication | No identity verification |
Error Response:
{
"error": "authentication_error",
"message": "Authentication service temporarily unavailable",
"status": 401
}
Layer 6: API Key Validation
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Database unavailable | DENY authentication | Cannot validate key |
| Hash comparison error | DENY authentication | Cannot verify key |
| Rate limit check fails | DENY request | Cannot enforce limits |
| Key lookup returns error | DENY authentication | Cannot confirm validity |
Error Response:
{
"error": "api_key_error",
"message": "API key validation failed",
"status": 401
}
Layer 7: RBAC Authorization
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Permission check fails | DENY authorization | Cannot confirm permissions |
| Role lookup fails | Assume RESTRICTED (level 0) | Minimum privileges |
| SoD check fails | Require additional approval | Cannot confirm dual control |
| User lookup fails | DENY authorization | Cannot confirm identity |
Error Response:
{
"error": "authorization_error",
"message": "Authorization check failed - access denied",
"status": 403
}
Layer 8: BYOK Encryption
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| KMS unavailable | FAIL operation | No unencrypted data storage |
| DEK decryption fails | FAIL operation | Cannot access encrypted data |
| CMK rotation in progress | Queue and retry | Maintain encryption |
| Key cache expired | Fetch new key or FAIL | No stale key usage |
Error Response:
{
"error": "encryption_error",
"message": "Encryption service unavailable - operation failed",
"operation_blocked": true
}
Layer 9: Audit Logging
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Audit write fails | BLOCK operation | Maintains compliance trail |
| Hash chain validation fails | Alert and investigate | Potential tampering |
| Database unavailable | BLOCK operation | No unaudited operations |
| Sequence number conflict | Retry or BLOCK | Maintains integrity |
Error Response:
{
"error": "audit_error",
"message": "Audit logging failed - operation blocked for compliance",
"compliance_requirement": "SOC2-CC7.1"
}
Note: The AUDIT_FAIL_OPEN=false environment variable controls this behavior. Setting it to true would allow operations to proceed without audit logging - NOT RECOMMENDED for production.
Layer 10: Input Validation
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Schema validation error | REJECT input | Prevents malformed data |
| Type coercion fails | REJECT input | Maintains type safety |
| Cross-field validation fails | REJECT input | Maintains data integrity |
| Validation library error | REJECT input | Cannot confirm validity |
Error Response:
{
"error": "validation_error",
"message": "Input validation failed",
"status": 422,
"details": [
{"field": "email", "error": "Invalid email format"}
]
}
Layer 11: Secrets Management
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Secrets Manager unavailable | BLOCK operation | Cannot access credentials |
| Secret not found | BLOCK operation | Cannot authenticate to external service |
| Secret expired | BLOCK and alert | Prevents use of compromised credentials |
| Decryption fails | BLOCK operation | Cannot access secret value |
Error Response:
{
"error": "secrets_error",
"message": "Required credentials unavailable - operation blocked"
}
Layer 12: Security Headers
| Failure Scenario | Default Behavior | Rationale |
|---|---|---|
| Header config missing | Apply strictest defaults | Maximum protection |
| CSP generation fails | Use restrictive default CSP | Prevents XSS |
| HSTS config error | Enable HSTS with max values | Prevents downgrade |
Default Headers (Applied on Any Error):
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
Configuration
Environment Variables
# Fail-secure configuration
SECURITY_FAIL_MODE=secure # Options: secure, open (NEVER use open in production)
AUDIT_FAIL_OPEN=false # If true, allows operations without audit (NOT RECOMMENDED)
AUTH_FAIL_OPEN=false # If true, allows unauthenticated access (NEVER RECOMMENDED)
RATE_LIMIT_FAIL_OPEN=false # If true, disables rate limiting on Redis failure
# Timeout configurations (fail-secure triggers on timeout)
PROMPT_SECURITY_TIMEOUT_MS=5000 # Timeout for prompt analysis
CODE_ANALYSIS_TIMEOUT_MS=10000 # Timeout for code analysis
JWT_VALIDATION_TIMEOUT_MS=3000 # Timeout for JWT validation
Override Considerations
Warning: Overriding fail-secure behavior should only be done in specific circumstances:
| Override | When Acceptable | When NOT Acceptable |
|---|---|---|
AUDIT_FAIL_OPEN=true | Development/testing only | Production environments |
RATE_LIMIT_FAIL_OPEN=true | Never | Any environment |
AUTH_FAIL_OPEN=true | Never | Any environment |
Compliance Mapping
| Framework | Control | Fail-Secure Requirement |
|---|---|---|
| SOC 2 | CC6.1 | Logical access controls must fail securely |
| SOC 2 | CC7.1 | System operations must maintain security during failures |
| HIPAA | 164.312(a)(1) | Access controls must be fail-secure |
| PCI-DSS | Req 6.5 | Application security must fail securely |
| NIST 800-53 | SC-24 | Fail in known state |
| NIST 800-53 | SI-17 | Fail-safe procedures |
Verification
Testing Fail-Secure Behavior
# Test rate limiting fail-secure (stop Redis first)
curl -X POST https://api.ascend.io/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "password": "test"}'
# Expected: 503 Service Unavailable (not 200 OK)
# Test audit fail-secure (simulate audit DB failure)
curl -X POST https://api.ascend.io/v1/actions/evaluate \
-H "Authorization: Bearer $TOKEN" \
-H "X-Test-Audit-Failure: true" \
-d '{"action_type": "execute_sql", "parameters": {}}'
# Expected: Operation blocked due to audit failure
# Verify fail-secure configuration
curl -X GET https://api.ascend.io/v1/admin/security/fail-secure-status \
-H "Authorization: Bearer $ADMIN_TOKEN"
Expected Response for Fail-Secure Status
{
"fail_secure_enabled": true,
"layers": {
"rate_limiting": {"fail_mode": "secure", "status": "active"},
"prompt_security": {"fail_mode": "secure", "status": "active"},
"code_analysis": {"fail_mode": "secure", "status": "active"},
"action_governance": {"fail_mode": "secure", "status": "active"},
"jwt_auth": {"fail_mode": "secure", "status": "active"},
"api_key_auth": {"fail_mode": "secure", "status": "active"},
"rbac": {"fail_mode": "secure", "status": "active"},
"encryption": {"fail_mode": "secure", "status": "active"},
"audit_logging": {"fail_mode": "secure", "status": "active"},
"input_validation": {"fail_mode": "secure", "status": "active"},
"secrets_management": {"fail_mode": "secure", "status": "active"},
"security_headers": {"fail_mode": "secure", "status": "active"}
},
"compliance_mode": "soc2_hipaa_pci",
"overrides_detected": []
}
Next Steps
- Authentication Overview - Authentication methods
- Authorization Overview - RBAC and permissions
- Compliance Overview - Compliance framework mapping