- Bumped the version of the `lol.mleku.dev` dependency from v1.0.3 to v1.0.4.
- Removed redundant checks for disabled policy in event handling.
- Introduced a `default_policy` field in the policy configuration, allowing for more flexible event handling based on default behaviors.
- Enhanced documentation to clarify the default policy logic and its implications on event processing.
- Updated tests to validate the new default policy behavior and ensure correct fallback mechanisms are in place.
5. **Default Policy** - Applied when no rules make a decision
### Global Rules
### Global Rules
@ -173,17 +186,41 @@ When policy is enabled, every EVENT envelope is checked using `CheckPolicy("writ
When policy is enabled, every event returned in REQ responses is filtered using `CheckPolicy("read", event, loggedInPubkey, ipAddress)` before being sent to the client. The same evaluation order applies for read access.
When policy is enabled, every event returned in REQ responses is filtered using `CheckPolicy("read", event, loggedInPubkey, ipAddress)` before being sent to the client. The same evaluation order applies for read access.
## Error Handling
## Script Resilience
The policy system is designed to be resilient to script failures:
- If policy script fails or times out, events are allowed by default
### Automatic Recovery
- Policy scripts are automatically restarted if they crash or fail to load
- The system continuously monitors script health and attempts recovery every 60 seconds (1 minute)
- Script failures don't disable the entire policy system
### Fallback Behavior
When a policy script fails or is not running:
- Events that would have been processed by the script fall back to the `default_policy`
- The system logs which policy rule is inactive and the fallback behavior
- Other policy rules (global, kinds, non-script rules) continue to function normally
### Error Handling
- If policy script fails or times out, events fall back to `default_policy` setting
- If policy configuration is invalid, default policy (allow all) is used
- If policy configuration is invalid, default policy (allow all) is used
- Policy script failures are logged but don't block relay operation
- Policy script failures are logged with specific rule information but don't block relay operation
## Monitoring
## Monitoring
Policy decisions are logged at debug level:
Policy decisions and script health are logged:
### Policy Decisions
- `policy allowed event <id>`
- `policy allowed event <id>`
- `policy rejected event <id>`
- `policy rejected event <id>`
### Script Health
- `policy rule for kind <N> is inactive (script not running), falling back to default policy (<policy>)`
- `policy rule for kind <N> failed (script processing error: <error>), falling back to default policy (<policy>)`
- `policy rule for kind <N> returned unknown action '<action>', falling back to default policy (<policy>)`
- `policy script not found at <path>, will retry periodically`
- `policy script crashed - events will fall back to default policy until restart`
- `policy filtered out event <id> for read access`
- `policy filtered out event <id> for read access`
// Kinds defines the filter for events by kind; the whitelist overrides the blacklist if it has any fields, and the blacklist is ignored (implicitly all not-whitelisted are blacklisted)
// Kinds defines whitelist and blacklist policies for event kinds.
// Whitelist takes precedence over blacklist - if whitelist is present, only whitelisted kinds are allowed.
// If only blacklist is present, all kinds except blacklisted ones are allowed.
typeKindsstruct{
typeKindsstruct{
// Whitelist is a list of event kinds that are allowed to be written to the relay. If any are present, implicitly all others are denied.
// Whitelist is a list of event kinds that are allowed to be written to the relay. If any are present, implicitly all others are denied.
Whitelist[]int`json:"whitelist,omitempty"`
Whitelist[]int`json:"whitelist,omitempty"`
@ -28,13 +30,16 @@ type Kinds struct {
Blacklist[]int`json:"blacklist,omitempty"`
Blacklist[]int`json:"blacklist,omitempty"`
}
}
// Rule is a rule for an event kind.
// Rule defines policy criteria for a specific event kind.
//
//
// If Script is present, it overrides all other criteria.
// Rules are evaluated in the following order:
// 1. If Script is present and running, it determines the outcome
// 2. If Script fails or is not running, falls back to default_policy
// 3. Otherwise, all specified criteria are evaluated as AND operations
//
//
// The criteria have mutual exclude semantics on pubkey white/blacklists, if whitelist has any fields, blacklist is ignored (implicitly all not-whitelisted are blacklisted).
// For pubkey allow/deny lists: whitelist takes precedence over blacklist.
//
// If whitelist has entries, only whitelisted pubkeys are allowed.
// The other criteria are evaluated as AND operations, everything specified must match for the event to be allowed to be written to the relay.
// If only blacklist has entries, all pubkeys except blacklisted ones are allowed.
typeRulestruct{
typeRulestruct{
// Description is a human-readable description of the rule.
// Description is a human-readable description of the rule.
// CheckPolicy checks if an event is allowed to be written to the relay based on the policy. The access parameter is either "write" or "read", write is for accepting events and read is for filtering events to send back to the client.
// CheckPolicy checks if an event is allowed based on the policy configuration.
// The access parameter should be "write" for accepting events or "read" for filtering events.
// Returns true if the event is allowed, false if denied, and an error if validation fails.
// Policy evaluation order: global rules → kind filtering → specific rules → default policy.