Overview
NeoSC is built with a Zero Trust architecture integrating Zitadel OIDC for authentication, Pomerium for access control, and NetBird for encrypted networking. This guide covers security hardening, MFA implementation, and policy enforcement.
Zero Trust Architecture
NeoSC implements Zero Trust principles:
Network Layer (NetBird)
WireGuard Encryption : All workspace connections use encrypted tunnels
No Open Ports : Direct connections blocked, all traffic through authenticated tunnels
Peer-to-Peer : Direct encrypted connections between clients and resources
# From infra/docker-compose.yml:19-26
networks :
proxy :
driver : bridge # Public network
internal :
driver : bridge
internal : true # No external access
Identity Layer (Zitadel + Pomerium)
OIDC Authentication : Zitadel provides identity verification
PKCE Flow : Enhanced security for public clients
Access Proxy : Pomerium validates every request before routing
# From infra/docker-compose.yml:44-74
pomerium :
image : pomerium/pomerium:latest
environment :
ZITADEL_CLIENT_ID : ${ZITADEL_CLIENT_ID}
ZITADEL_CLIENT_SECRET : ${ZITADEL_CLIENT_SECRET}
Session Layer
All workspace sessions are monitored and auditable:
# From backend/server.py:78-91
class Session ( BaseModel ):
id : str
user_id: str
workspace_id: str
status: str # active, disconnected, terminated
tunnel_status: str = "encrypted"
mfa_verified: bool = True
Multi-Factor Authentication
MFA Enforcement
NeoSC enforces MFA through security policies:
# From backend/server.py:768-774
{
"id" : "pol-mfa-required" ,
"name" : "MFA Required" ,
"description" : "Enforce multi-factor authentication for all users" ,
"type" : "access" ,
"rules" : [ "Require MFA for login" , "WebAuthn preferred" , "TOTP as fallback" ]
}
MFA Status Tracking
All users have MFA enabled by default:
# From backend/server.py:41-49
class User ( BaseModel ):
id : str
email: str
name: str
organization: str = "Default Organization"
role: str = "user"
mfa_enabled: bool = True # Default enabled
WebAuthn/FIDO2 implementation is currently in development (P1 priority). MFA is enforced at the Zitadel SSO layer for SSO users. Local auth users should migrate to SSO for full MFA support.
Implementing MFA with Zitadel
Enable MFA in Zitadel
Configure MFA policies in Zitadel management console:
Navigate to Organization Settings → Login Policy
Enable “Multi-Factor Authentication”
Select allowed methods: WebAuthn, OTP, SMS
Enforce MFA for NeoSC project
In Zitadel project settings:
Select your NeoSC application
Enable “Force MFA” option
Set MFA grace period if needed
Verify MFA in sessions
NeoSC tracks MFA verification in session objects: # backend/server.py:619-660
session = Session(
user_id = user[ 'id' ],
mfa_verified = user.get( 'mfa_enabled' , True )
)
WebAuthn Registration (Planned)
Future implementation will support:
Hardware security keys (YubiKey, Titan, etc.)
Platform authenticators (Touch ID, Windows Hello)
Passwordless authentication
Security Policies
NeoSC implements three core security policies:
1. MFA Required Policy
# backend/server.py:768-774
{
"id" : "pol-mfa-required" ,
"type" : "access" ,
"enabled" : True ,
"rules" : [
"Require MFA for login" ,
"WebAuthn preferred" ,
"TOTP as fallback"
]
}
Enforcement : Integrated with Zitadel authentication flow.
2. Zero Trust Network Policy
# backend/server.py:776-782
{
"id" : "pol-network-zero-trust" ,
"type" : "network" ,
"enabled" : True ,
"rules" : [
"No direct connections" ,
"WireGuard encryption" ,
"Identity verification"
]
}
Enforcement : NetBird tunnels required for internal resource access.
3. Session Recording Policy
# backend/server.py:784-791
{
"id" : "pol-session-recording" ,
"type" : "session" ,
"enabled" : True ,
"rules" : [
"Record screen activity" ,
"Log keystrokes for audit" ,
"30-day retention"
]
}
Session recording playback is planned for P1 implementation. Recording infrastructure requires VDI backend integration (Kasm/Guacamole).
Managing Policies
Admins can toggle policies via API:
PATCH /api/policies/{policy_id}
Authorization: Bearer < admin_toke n >
Implementation:
# backend/server.py:805-819
@api_router.patch ( "/policies/ {policy_id} " )
async def toggle_policy ( policy_id : str , user : dict = Depends(get_current_user)):
policy = await db.policies.find_one({ "id" : policy_id})
new_status = not policy.get( 'enabled' , True )
await db.policies.update_one({ "id" : policy_id}, { "$set" : { "enabled" : new_status}})
Disabling security policies reduces system security posture. All policy changes are logged to audit trail for compliance review.
Authentication Security
Password Security
Local authentication uses SHA-256 hashing:
# backend/server.py:126-127
def hash_password ( password : str ) -> str :
return hashlib.sha256(password.encode()).hexdigest()
Security Recommendation : Upgrade to bcrypt or Argon2 for production deployments. SHA-256 is vulnerable to rainbow table attacks despite being cryptographically secure.
Recommended implementation :
import bcrypt
def hash_password ( password : str ) -> str :
return bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
def verify_password ( password : str , hash : str ) -> bool :
return bcrypt.checkpw(password.encode(), hash .encode())
Token Management
Bearer tokens are generated using cryptographically secure random:
# backend/server.py:129-130
def generate_token () -> str :
return secrets.token_urlsafe( 32 ) # 256 bits of entropy
Token storage : In-memory dictionary (development)
active_tokens = {} # backend/server.py:133
Production Recommendation : Use Redis or JWT with refresh tokens for token persistence across server restarts and horizontal scaling.
SSO Security (Zitadel)
Zitadel integration uses PKCE for enhanced security:
# backend/server.py:326-436
@api_router.post ( "/auth/token-exchange" )
async def token_exchange ( request : TokenExchangeRequest):
# Exchange authorization code for tokens
token_response = await http_client.post(
f " { authority } /oauth/v2/token" ,
data = {
'grant_type' : 'authorization_code' ,
'client_id' : client_id,
'code' : request.code,
'redirect_uri' : request.redirect_uri,
'code_verifier' : request.code_verifier, # PKCE verification
}
)
PKCE Benefits :
Prevents authorization code interception
No client secret required for public clients
Secure for single-page applications
Network Security
Pomerium Access Proxy
All external traffic routes through Pomerium:
# infra/docker-compose.yml:44-74
pomerium :
networks :
- proxy # External access
- internal # Backend access
ports :
- "443:443"
- "80:80" # Redirect to HTTPS
Security features :
TLS termination
OIDC authentication before routing
Header injection for user context
No direct backend exposure
Internal Network Isolation
# infra/docker-compose.yml:80-102
frontend :
networks :
- internal # No external ports
# Accessed only via Pomerium at portal.kappa4.com
backend :
networks :
- internal # No external ports
# Accessed only via Pomerium at api.portal.kappa4.com
CORS Configuration
Backend restricts cross-origin requests:
# backend/server.py:846-852
app.add_middleware(
CORSMiddleware,
allow_credentials = True ,
allow_origins = os.environ.get( 'CORS_ORIGINS' , '*' ).split( ',' ),
allow_methods = [ "*" ],
allow_headers = [ "*" ],
)
Set CORS_ORIGINS to specific domains in production: CORS_ORIGINS = https://portal.kappa4.com,https://gate.kappa4.com
Audit and Compliance
Comprehensive Audit Logging
All security-relevant events are logged:
# backend/server.py:94-103
class AuditLog ( BaseModel ):
id : str
user_id: str
user_email: str
action: str
resource: str
details: str
ip_address: str = "192.168.1.1"
timestamp: datetime
success: bool = True
Logged Security Events
Action Resource Details registerauthUser registration with organization loginauthLocal authentication attempt sso_loginauthSSO login with provider and role logoutauthSession termination toggle_policypolicy:{id}Policy enabled/disabled launch_workspaceworkspace:{id}Workspace launch with security context disconnect_sessionsession:{id}Session disconnection
Audit Log Access
GET /api/audit-logs
Authorization: Bearer < toke n >
Access control :
# backend/server.py:739-744
@api_router.get ( "/audit-logs" )
async def get_audit_logs ( user : dict = Depends(get_current_user)):
# Admins see all, users see only their own
query = {} if user.get( 'role' ) == 'admin' else { "user_id" : user[ 'id' ]}
Compliance Features
SOC 2 Type II Audit logs provide evidence for access controls, monitoring, and incident response requirements.
GDPR Compliance User consent tracking, data access logs, and retention policies support data protection requirements.
ISO 27001 Security policies, access controls, and audit trails align with information security management standards.
HIPAA Session recording and encrypted tunnels support healthcare data protection requirements.
Security Checklist
Enable SSO
Configure Zitadel SSO for all users instead of local authentication:
Centralized credential management
MFA enforcement at IdP level
Automatic role provisioning
Enforce MFA
Verify MFA policy is enabled: GET /api/policies/pol-mfa-required
# Ensure "enabled": true
Configure Pomerium
Set up TLS certificates and authentication:
Use valid TLS certificates (Let’s Encrypt or corporate CA)
Configure Zitadel as IdP in Pomerium
Set secure cookie secrets
Deploy NetBird
Roll out NetBird client to all users:
Install NetBird on workstations
Authenticate against management server
Verify tunnel connectivity
Review Audit Logs
Regularly monitor for suspicious activity: GET /api/audit-logs?success= false
# Review failed authentication attempts
Rotate Secrets
Update credentials periodically:
Pomerium shared secret
Pomerium cookie secret
JWT signing keys
Database credentials
Environment Security
Production Environment Variables
Backend (backend/.env):
MONGO_URL = mongodb://mongo:27017/neosc
DB_NAME = neosc
JWT_SECRET =< strong-random-secret >
ZITADEL_AUTHORITY = https://manager.kappa4.com
ZITADEL_CLIENT_ID =< your-client-id >
ZITADEL_CLIENT_SECRET =< your-client-secret >
ZITADEL_PROJECT_ID =< your-project-id >
CORS_ORIGINS = https://portal.kappa4.com
TRUST_POMERIUM_HEADERS = true
Pomerium (.env):
ZITADEL_CLIENT_ID =< your-client-id >
ZITADEL_CLIENT_SECRET =< your-client-secret >
POMERIUM_SHARED_SECRET =< 256-bit-base64 >
POMERIUM_COOKIE_SECRET =< 256-bit-base64 >
Never commit secrets to version control . Use secret management solutions:
Docker secrets
Kubernetes secrets
HashiCorp Vault
AWS Secrets Manager
Secret Generation
Generate secure secrets:
# Pomerium shared secret (256 bits)
openssl rand -base64 32
# Pomerium cookie secret (256 bits)
openssl rand -base64 32
# JWT secret
openssl rand -hex 32
Incident Response
Detecting Security Events
Failed authentication attempts :
GET /api/audit-logs
# Filter for success: false, action: login
Unauthorized access attempts :
# Monitor 403 Forbidden responses in Pomerium logs
docker logs pomerium | grep "403"
Suspicious session activity :
GET /api/sessions
# Check for unusual IP addresses or session durations
Response Procedures
Identify the threat
Review audit logs to determine scope and impact of security event.
Contain the breach
Immediately revoke compromised credentials: # Force logout
POST /api/auth/logout
Authorization: Bearer < compromised_toke n >
Disable affected accounts
For SSO users, disable in Zitadel. For local users, consider implementing account suspension endpoint.
Rotate secrets
Update all authentication secrets and redeploy services.
Document incident
Create incident report including:
Timeline of events
Affected users and resources
Response actions taken
Preventive measures implemented
Best Practices Summary
Use Zitadel SSO instead of local authentication
Enforce MFA for all users, especially admins
Rotate JWT secrets every 90 days
Implement account lockout after failed attempts (future)
Follow principle of least privilege
Assign admin role only when necessary
Review role assignments quarterly
Audit admin actions regularly
Require NetBird tunnels for all internal resources
Use Pomerium for external access only
Disable direct backend/frontend port exposure
Implement network segmentation
Enable all security policies
Review audit logs weekly
Set up alerts for failed authentications
Monitor session durations and IP addresses
Encrypt data at rest (MongoDB encryption)
Use TLS for all network traffic
Implement session recording for compliance
Define data retention policies