Add extensive tests and improve policy configuration handling
Some checks failed
Go / build-and-release (push) Has been cancelled

Introduce comprehensive tests for policy validation logic, including owner and policy admin scenarios. Update `HandlePolicyConfigUpdate` to differentiate permissions for owners and policy admins, enforcing stricter field restrictions and validation flows.
This commit is contained in:
2025-12-02 07:51:59 +00:00
parent dd8027478c
commit 70944d45df
8 changed files with 1627 additions and 46 deletions

View File

@@ -1111,20 +1111,62 @@ Check logs for policy decisions and errors.
## Dynamic Policy Configuration via Kind 12345
Policy administrators can update the relay policy dynamically by publishing kind 12345 events. This enables runtime policy changes without relay restarts.
Both **owners** and **policy admins** can update the relay policy dynamically by publishing kind 12345 events. This enables runtime policy changes without relay restarts, with different permission levels for each role.
### Role Hierarchy and Permissions
ORLY uses a layered permission model for policy updates:
| Role | Source | Can Modify | Restrictions |
|------|--------|------------|--------------|
| **Owner** | `ORLY_OWNERS` env or `owners` in policy.json | All fields | Owners list must remain non-empty |
| **Policy Admin** | `policy_admins` in policy.json | Extend rules, add blacklists | Cannot modify `owners` or `policy_admins`, cannot reduce permissions |
### Composition Rules
Policy updates from owners and policy admins compose as follows:
1. **Owner policy is the base** - Defines minimum permissions and protected fields
2. **Policy admins can extend** - Add to allow lists, add new kinds, add blacklists
3. **Blacklists override whitelists** - Policy admins can ban users that owners allowed
4. **Protected fields are immutable** - Only owners can modify `owners` and `policy_admins`
#### What Policy Admins CAN Do:
- ✅ Add pubkeys to `write_allow` and `read_allow` lists
- ✅ Add entries to `write_deny` and `read_deny` lists to blacklist malicious users
- ✅ Blacklist any non-admin user, even if whitelisted by owners or other admins
- ✅ Add kinds to `kind.whitelist` and `kind.blacklist`
- ✅ Increase size limits (`size_limit`, `content_limit`, etc.)
- ✅ Add rules for new kinds not defined by owners
- ✅ Enable `write_allow_follows` for additional rules
#### What Policy Admins CANNOT Do:
- ❌ Modify the `owners` field
- ❌ Modify the `policy_admins` field
- ❌ Blacklist owners or other policy admins (protected users)
- ❌ Remove pubkeys from allow lists
- ❌ Remove kinds from whitelist
- ❌ Reduce size limits
- ❌ Remove rules defined by owners
- ❌ Add new required tags (restrictions)
### Enabling Dynamic Policy Updates
1. Add yourself as a policy admin in the initial policy.json:
1. Set yourself as both owner and policy admin in the initial policy.json:
```json
{
"default_policy": "allow",
"policy_admins": ["YOUR_HEX_PUBKEY_HERE"],
"owners": ["YOUR_HEX_PUBKEY_HERE"],
"policy_admins": ["ADMIN_HEX_PUBKEY_HERE"],
"policy_follow_whitelist_enabled": false
}
```
**Important:** The `owners` list must contain at least one pubkey to prevent lockout.
2. Ensure policy is enabled:
```bash
@@ -1135,15 +1177,28 @@ export ORLY_POLICY_ENABLED=true
Send a kind 12345 event with the new policy configuration as JSON content:
**As Owner (full control):**
```json
{
"kind": 12345,
"content": "{\"default_policy\": \"deny\", \"kind\": {\"whitelist\": [1,3,7]}, \"policy_admins\": [\"YOUR_HEX_PUBKEY\"]}",
"content": "{\"default_policy\": \"deny\", \"owners\": [\"OWNER_HEX\"], \"policy_admins\": [\"ADMIN_HEX\"], \"kind\": {\"whitelist\": [1,3,7]}}",
"tags": [],
"created_at": 1234567890
}
```
**As Policy Admin (extensions only):**
```json
{
"kind": 12345,
"content": "{\"default_policy\": \"deny\", \"owners\": [\"OWNER_HEX\"], \"policy_admins\": [\"ADMIN_HEX\"], \"kind\": {\"whitelist\": [1,3,7,30023], \"blacklist\": [4]}, \"rules\": {\"1\": {\"write_deny\": [\"BAD_ACTOR_HEX\"]}}}",
"tags": [],
"created_at": 1234567890
}
```
Note: Policy admins must include the original `owners` and `policy_admins` values unchanged.
### Policy Admin Follow List Whitelisting
When `policy_follow_whitelist_enabled` is `true`, the relay automatically grants access to all pubkeys followed by policy admins.
@@ -1161,10 +1216,27 @@ When `policy_follow_whitelist_enabled` is `true`, the relay automatically grants
### Security Considerations
- Only pubkeys listed in `policy_admins` can update the policy
- Policy updates are validated before applying (invalid JSON or pubkeys are rejected)
- Failed updates preserve the existing policy (no corruption)
- All policy updates are logged for audit purposes
- **Privilege separation**: Only owners can add/remove owners and policy admins
- **Non-empty owners**: At least one owner must always exist to prevent lockout
- **Protected fields**: Policy admins cannot escalate their privileges by modifying `owners`
- **Blacklist override**: Policy admins can block bad actors even if owners allowed them
- **Validation first**: Policy updates are validated before applying (invalid updates are rejected)
- **Atomic updates**: Failed updates preserve the existing policy (no corruption)
- **Audit logging**: All policy updates are logged with the submitter's pubkey
### Error Messages
Common validation errors:
| Error | Cause |
|-------|-------|
| `owners list cannot be empty` | Owner tried to remove all owners |
| `cannot modify the 'owners' field` | Policy admin tried to change owners |
| `cannot modify the 'policy_admins' field` | Policy admin tried to change admins |
| `cannot remove kind X from whitelist` | Policy admin tried to reduce permissions |
| `cannot reduce size_limit for kind X` | Policy admin tried to make limits stricter |
| `cannot blacklist owner X` | Policy admin tried to blacklist an owner |
| `cannot blacklist policy admin X` | Policy admin tried to blacklist another admin |
## Testing the Policy System