tinyhumansai/openhuman · error

Command blocked by security policy: {cmd}

Error message

Command blocked by security policy: {cmd}

What it means

Before persisting a new command, update_cron_job runs it through SecurityPolicy built from config.autonomy, workspace_dir and action_dir. If is_command_allowed(cmd) is false — the command class is not permitted at the current tier, or the command hits unconditionally forbidden system/credential paths — the update bails without touching the job.

Source

Thrown at src/openhuman/cron/ops.rs:115

            _ => anyhow::bail!("Cannot update expression/tz on a non-cron schedule"),
        };
        Some(Schedule::Cron {
            expr: expression.unwrap_or(existing_expr),
            tz: tz.or(existing_tz),
            active_hours: existing_active,
        })
    } else {
        None
    };

    if let Some(ref cmd) = command {
        let security = SecurityPolicy::from_config(
            &config.autonomy,
            &config.workspace_dir,
            &config.action_dir,
        );
        if !security.is_command_allowed(cmd) {
            anyhow::bail!("Command blocked by security policy: {cmd}");
        }
    }

    let patch = CronJobPatch {
        schedule,
        command,
        name,
        ..CronJobPatch::default()
    };

    update_job(config, id, patch)
}

/// Parse a human-friendly delay string (e.g. "5m", "2h", "30s") into a
/// `chrono::Duration`. Defaults to minutes when no unit is given.
pub fn parse_human_delay(input: &str) -> Result<chrono::Duration> {
    let input = input.trim();
    if input.is_empty() {

View on GitHub (pinned to 7491200858)

Solutions

  1. Choose a command the current tier allows (read-only commands under readonly)
  2. Adjust the autonomy tier / workspace_only / trusted_roots via the config.update_autonomy_settings RPC (Settings → Agent access) and retry
  3. If the command is genuinely required but policy must stay strict, run it from a context outside the policy scope rather than weakening the tier globally

Example fix

# before
[autonomy]
tier = "readonly"
# --command 'rsync ...' is Write-class: blocked

# after
[autonomy]
tier = "supervised"
# Write-class commands pass is_command_allowed at this tier
Defensive patterns

Strategy: validation

Validate before calling

// Mirror the exact guard before attempting the update
let security = SecurityPolicy::from_config(&config.autonomy, &config.workspace_dir, &config.action_dir);
if !security.is_command_allowed(cmd) {
    return Err(format!("'{cmd}' not allowed at the current autonomy tier"));
}

Try / catch

Catch the bail and rekey it to a policy-denied outcome (distinct from store errors) so the UI can offer 'adjust agent access' instead of a generic failure.

Prevention

When it happens

Trigger: `openhuman cron update <id> --command 'curl ... | sh'` under a readonly/supervised tier; commands whose classify_command result (Network/Install/Destructive, or unrecognized which defaults to Write) is gated by the tier; commands touching always-forbidden directories.

Common situations: Hardening autonomy down to readonly and then editing existing cron jobs; CI containers with a strict [autonomy] block; a command that was fine at creation time but policy has since tightened.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/0055207fd7e883bd. Report an issue: GitHub.