Thoryn

Policy rules · Policy rules

Time gate — business hours only

ALLOW only on weekdays between 09:00 and 18:00 local time. Use it for back-office systems that should be unreachable outside business hours.

Tested against:policyEngine: 1.0.0

policy-engine recipe — shared category architecture: how this pattern composes with Hub, Broker, and the rest of the catalog

Use case

A back-office admin tool — payroll, financial settlement, regulatory submission — that should only be reachable on a weekday during business hours. Out-of-hours access is a high-confidence signal of either misuse or a compromised credential.

Rule

{
  "all": [
    { "fact": "now_dow", "operator": "in", "value": ["MON", "TUE", "WED", "THU", "FRI"] },
    { "fact": "now_hour_local", "operator": "greaterThanOrEqual", "value": 9 },
    { "fact": "now_hour_local", "operator": "lessThan", "value": 18 }
  ]
}

Facts shape

The host service computes now_dow and now_hour_local before evaluation — Policy Engine has no built-in time access (it's deterministic and stateless on purpose).

val now = Instant.now().atZone(operatorTimezone)
val facts = mapOf(
  "now_dow" to now.dayOfWeek.name.take(3),  // "MON" .. "SUN"
  "now_hour_local" to now.hour
)

Trace — DENY (Saturday)

{
  "decision": "DENY",
  "trace": [
    { "all": [
        { "fact": "now_dow", "operator": "in", "value": ["MON","TUE","WED","THU","FRI"], "actual": "SAT", "result": "fail" }
      ],
      "result": "fail"
    }
  ]
}

When to use

  • High-risk back-office tools where 24/7 availability is not a feature
  • Compliance regimes that explicitly require business-hours-only access (some sector regulators)

When not to use

  • Customer-facing surfaces — they need to be reachable any time
  • Globally distributed teams — pin now_hour_local to the operator's timezone, not the user's

See also