- Remove KCL ecosystem (~220 files deleted) - Migrate all infrastructure to Nickel schema system - Consolidate documentation: legacy docs → provisioning/docs/src/ - Add CI/CD workflows (.github/) and Rust build config (.cargo/) - Update core system for Nickel schema parsing - Update README.md and CHANGES.md for v5.0.0 release - Fix pre-commit hooks: end-of-file, trailing-whitespace - Breaking changes: KCL workspaces require migration - Migration bridge available in docs/src/development/
140 lines
4.5 KiB
Plaintext
140 lines
4.5 KiB
Plaintext
# Control Center Validators
|
|
# JWT, RBAC, policies, compliance, and security validation
|
|
|
|
let constraints = import "../constraints/constraints.toml" in
|
|
let common = import "./common-validator.ncl" in
|
|
let string_val = import "./string-validator.ncl" in
|
|
|
|
{
|
|
# Validate JWT token expiration in seconds
|
|
ValidJwtTokenExpiration = fun expiration =>
|
|
common.ValidRange
|
|
constraints.control_center.jwt.token_expiration.min
|
|
constraints.control_center.jwt.token_expiration.max
|
|
expiration,
|
|
|
|
# Validate JWT refresh token expiration
|
|
ValidJwtRefreshExpiration = fun expiration =>
|
|
common.ValidRange
|
|
constraints.control_center.jwt.refresh_expiration.min
|
|
constraints.control_center.jwt.refresh_expiration.max
|
|
expiration,
|
|
|
|
# Validate JWT issuer
|
|
ValidJwtIssuer = fun issuer =>
|
|
string_val.ValidIdentifier issuer,
|
|
|
|
# Validate JWT audience
|
|
ValidJwtAudience = fun audience =>
|
|
string_val.ValidIdentifier audience,
|
|
|
|
# Validate rate limiting max requests
|
|
ValidRateLimitMaxRequests = fun requests =>
|
|
common.ValidRange
|
|
constraints.control_center.rate_limiting.max_requests.min
|
|
constraints.control_center.rate_limiting.max_requests.max
|
|
requests,
|
|
|
|
# Validate rate limiting window in seconds
|
|
ValidRateLimitWindow = fun window =>
|
|
common.ValidRange
|
|
constraints.control_center.rate_limiting.window_seconds.min
|
|
constraints.control_center.rate_limiting.window_seconds.max
|
|
window,
|
|
|
|
# Validate session max duration in seconds
|
|
ValidSessionMaxDuration = fun duration =>
|
|
common.ValidRange
|
|
constraints.control_center.session.max_duration.min
|
|
constraints.control_center.session.max_duration.max
|
|
duration,
|
|
|
|
# Validate MFA max attempts
|
|
ValidMfaMaxAttempts = fun attempts =>
|
|
common.ValidRange
|
|
constraints.control_center.mfa.max_attempts.min
|
|
constraints.control_center.mfa.max_attempts.max
|
|
attempts,
|
|
|
|
# Validate audit log retention in days
|
|
ValidAuditRetentionDays = fun days =>
|
|
common.ValidRange
|
|
constraints.control_center.audit.retention_days.min
|
|
constraints.control_center.audit.retention_days.max
|
|
days,
|
|
|
|
# Validate role name
|
|
ValidRoleName = fun role =>
|
|
string_val.ValidIdentifier role,
|
|
|
|
# Validate policy name
|
|
ValidPolicyName = fun policy =>
|
|
string_val.ValidIdentifier policy,
|
|
|
|
# Validate RBAC configuration consistency
|
|
ValidRbacConfig = fun rbac_config =>
|
|
if rbac_config.enabled && rbac_config.default_role == "" then
|
|
std.contract.blame_with_message
|
|
"RBAC enabled but default_role is empty"
|
|
rbac_config
|
|
else if !rbac_config.enabled && rbac_config.hierarchy then
|
|
std.contract.blame_with_message
|
|
"RBAC hierarchy cannot be enabled when RBAC is disabled"
|
|
rbac_config
|
|
else
|
|
rbac_config,
|
|
|
|
# Validate policy cache TTL
|
|
ValidPolicyCacheTtl = fun ttl =>
|
|
if ttl < 1 then
|
|
std.contract.blame_with_message "Policy cache TTL must be >= 1 second" ttl
|
|
else if ttl > 86400 then
|
|
std.contract.blame_with_message "Policy cache TTL must be <= 86400 seconds" ttl
|
|
else
|
|
ttl,
|
|
|
|
# Validate max policies in cache
|
|
ValidMaxPoliciesInCache = fun count =>
|
|
if count < 10 then
|
|
std.contract.blame_with_message "Max policies must be >= 10" count
|
|
else if count > 100000 then
|
|
std.contract.blame_with_message "Max policies must be <= 100000" count
|
|
else
|
|
count,
|
|
|
|
# Validate max policy versions
|
|
ValidMaxPolicyVersions = fun count =>
|
|
if count < 1 then
|
|
std.contract.blame_with_message "Max policy versions must be >= 1" count
|
|
else if count > 100 then
|
|
std.contract.blame_with_message "Max policy versions must be <= 100" count
|
|
else
|
|
count,
|
|
|
|
# Validate data retention years for compliance
|
|
ValidDataRetentionYears = fun years =>
|
|
if years < 1 then
|
|
std.contract.blame_with_message "Data retention must be >= 1 year" years
|
|
else if years > 10 then
|
|
std.contract.blame_with_message "Data retention must be <= 10 years" years
|
|
else
|
|
years,
|
|
|
|
# Validate LDAP configuration completeness
|
|
ValidLdapConfig = fun ldap_config =>
|
|
if ldap_config.enabled then
|
|
if ldap_config.server_url == null || ldap_config.server_url == "" then
|
|
std.contract.blame_with_message
|
|
"LDAP enabled but server_url is empty"
|
|
ldap_config
|
|
else
|
|
ldap_config
|
|
else
|
|
ldap_config,
|
|
|
|
# Validate compliance framework selection
|
|
ValidComplianceFramework = fun framework =>
|
|
let valid_frameworks = ['soc2, 'hipaa, 'pci_dss, 'gdpr] in
|
|
common.ValidEnum valid_frameworks framework,
|
|
}
|