Policy Conditions
Policy conditions are runtime checks that must all pass before a policy’s effect is applied. Conditions allow you to enforce context-aware access control — restricting access based on when, where, and how an identity is operating.
A policy with multiple conditions requires all conditions to be satisfied (logical AND). If any condition fails, the policy does not match.
Condition Types
VeraID supports six condition types. Each condition is a JSON object with a type field and type-specific configuration.
1. Time Window
Restrict access to specific days and hours. Useful for limiting CI/CD pipelines to business hours or preventing automated deployments during maintenance windows.
{ "type": "TIME_WINDOW", "timezone": "UTC", "windows": [ { "days": ["MON", "TUE", "WED", "THU", "FRI"], "startTime": "09:00", "endTime": "17:00" } ]}| Field | Type | Description |
|---|---|---|
type | string | Must be TIME_WINDOW. |
timezone | string | IANA timezone identifier. Default: UTC. |
windows | object[] | One or more time windows. Access is allowed if the current time falls within any window. |
windows[].days | string[] | Days of the week: MON, TUE, WED, THU, FRI, SAT, SUN. |
windows[].startTime | string | Start time in HH:MM (24-hour) format, inclusive. |
windows[].endTime | string | End time in HH:MM (24-hour) format, inclusive. |
2. IP Range
Restrict access to specific IP addresses or CIDR ranges. Commonly used to limit service account access to known office networks, VPN ranges, or cloud provider IP blocks.
{ "type": "IP_RANGE", "allowedRanges": [ "10.0.0.0/8", "172.16.0.0/12", "192.168.1.0/24" ], "deniedRanges": [ "10.0.99.0/24" ]}| Field | Type | Description |
|---|---|---|
type | string | Must be IP_RANGE. |
allowedRanges | string[] | CIDR ranges from which access is permitted. |
deniedRanges | string[] | CIDR ranges explicitly blocked, even if they fall within an allowed range. |
Example: Office network only
{ "type": "IP_RANGE", "allowedRanges": ["10.0.0.0/8"], "deniedRanges": []}This restricts access to the RFC 1918 10.0.0.0/8 private range, commonly used for corporate networks.
3. Rate Limit
Cap the number of requests an identity can make within a sliding time window. Protects against runaway automation, compromised credentials, and denial-of-service patterns.
{ "type": "RATE_LIMIT", "maxRequests": 1000, "windowSeconds": 3600}| Field | Type | Description |
|---|---|---|
type | string | Must be RATE_LIMIT. |
maxRequests | integer | Maximum number of requests allowed within the window. |
windowSeconds | integer | Duration of the sliding window in seconds. |
The example above limits an identity to 1,000 requests per hour (3,600 seconds). Once the limit is reached, the policy no longer matches and access is denied until the window resets.
Common rate limit configurations:
| Use Case | maxRequests | windowSeconds | Effective Rate |
|---|---|---|---|
| Standard API consumer | 1,000 | 3,600 | ~17 req/min |
| High-throughput pipeline | 10,000 | 3,600 | ~167 req/min |
| Batch job (conservative) | 100 | 60 | ~1.7 req/sec |
| AI agent (cost control) | 500 | 86,400 | 500 req/day |
4. Geo-Fencing
Restrict access based on the geographic origin of the request. Useful for data residency compliance (GDPR, CCPA) and reducing attack surface from unexpected regions.
{ "type": "GEO_FENCE", "allowedCountries": ["US", "DE", "FR", "GB", "IE"], "blockedCountries": ["KP", "IR", "CU"], "allowedRegions": ["us-east-1", "eu-west-1"]}| Field | Type | Description |
|---|---|---|
type | string | Must be GEO_FENCE. |
allowedCountries | string[] | ISO 3166-1 alpha-2 country codes from which access is allowed. |
blockedCountries | string[] | Country codes explicitly denied, even if listed in allowedCountries. |
allowedRegions | string[] | Cloud provider region identifiers (e.g., us-east-1, europe-west1). |
Example: US and EU only
{ "type": "GEO_FENCE", "allowedCountries": ["US", "DE", "FR", "GB", "NL", "IE"], "blockedCountries": [], "allowedRegions": []}5. Risk Score
Require the identity’s current risk score to be below a specified threshold. Risk scores are dynamically computed based on credential hygiene, behavioral patterns, and security posture.
{ "type": "RISK_SCORE", "maxRiskScore": 50, "riskFactors": ["credential_age", "permission_scope", "activity_anomaly"]}| Field | Type | Description |
|---|---|---|
type | string | Must be RISK_SCORE. |
maxRiskScore | integer | Maximum acceptable risk score (0-100). Identities above this threshold are denied. |
riskFactors | string[] | Optional. Specific risk factors to evaluate. If omitted, the aggregate score is used. |
Risk score ranges:
| Score Range | Risk Level | Typical Action |
|---|---|---|
| 0–20 | Low | Full access |
| 21–40 | Moderate | Standard access with monitoring |
| 41–60 | Elevated | Restricted access, review recommended |
| 61–80 | High | Limited access, investigation required |
| 81–100 | Critical | Access suspended, immediate remediation |
6. MFA Requirement
Require multi-factor authentication for sensitive operations. This condition verifies that the human owner of the NHI has completed an MFA challenge within a specified time window before the identity can perform the action.
{ "type": "MFA_REQUIRED", "maxAgeSeconds": 3600, "allowedMethods": ["totp", "webauthn", "push"]}| Field | Type | Description |
|---|---|---|
type | string | Must be MFA_REQUIRED. |
maxAgeSeconds | integer | Maximum age of the MFA verification in seconds. The owner must have verified within this window. |
allowedMethods | string[] | Accepted MFA methods: totp, webauthn, push, sms. |
Example: Require MFA for secret rotation
{ "name": "secret-rotation-mfa", "effect": "ALLOW", "subjects": ["group:secret-managers"], "resources": ["secrets:*"], "actions": ["rotate:*", "write:*"], "conditions": [ { "type": "MFA_REQUIRED", "maxAgeSeconds": 300, "allowedMethods": ["webauthn", "totp"] } ], "isActive": true}This policy requires the identity’s human owner to have completed a WebAuthn or TOTP challenge within the last 5 minutes before the identity can rotate or write secrets.
Combining Conditions
A policy can include multiple conditions. All conditions must pass for the policy to match (logical AND). This allows you to build layered access rules.
Example: Business hours + office IP + rate limited
{ "name": "ci-deploy-restricted", "description": "Allow CI/CD deployments only during business hours, from the office network, with rate limiting", "effect": "ALLOW", "subjects": ["group:ci-cd-runners"], "resources": ["prod:deployments:*"], "actions": ["deploy:*"], "conditions": [ { "type": "TIME_WINDOW", "timezone": "America/New_York", "windows": [ { "days": ["MON", "TUE", "WED", "THU", "FRI"], "startTime": "09:00", "endTime": "17:00" } ] }, { "type": "IP_RANGE", "allowedRanges": ["10.0.0.0/8"], "deniedRanges": [] }, { "type": "RATE_LIMIT", "maxRequests": 50, "windowSeconds": 3600 } ], "isActive": true}This policy allows CI/CD runners to deploy to production only when all three conditions are met:
- The request occurs during weekday business hours (Eastern time).
- The request originates from the
10.0.0.0/8network. - The identity has not exceeded 50 deployments in the last hour.
Next Steps
- Policy Evaluation — Learn how VeraID resolves policies with multiple conditions and conflicting effects.
- Policy Overview — Review the full policy structure and PBAC model.