· Updated

Gitlawb Zero Just Got Paranoid About Permissions — And You Should Be Too

Gitlawb Zero#gitlawb-zero#permissions#security#malformed-payload#agent-security#supply-chain

Gitlawb Zero handles permissions differently than other agents. Instead of asking for every permission upfront (the “blanket consent” model), it prompts you in the moment when a tool needs access — and you decide case by case. This just-in-time consent model is more secure if the prompt accurately represents what’s being requested.

But what if the prompt itself lies?

The Vulnerability: Malformed Permission Payloads

Zero’s permission system works by sending a structured payload describing what the tool wants to do — "tool X needs to read file Y" — and the user approves or rejects it. The bug: if the payload was malformed (missing fields, wrong types, corrupted, or deliberately crafted), Zero would still present the prompt to the user.

A malformed payload could mask what the tool is actually trying to access. The user sees "tool X wants to read file Y" but the actual access requested is something else entirely — perhaps writing to ~/.ssh/id_rsa, reading .env files, or executing a shell command.

Attack Scenarios This Enables

Scenario Malformed Payload User Sees Actual Action
Field injection Extra action: "write" alongside action: "read" “Read config.yaml” Writes to config.yaml
Path traversal path: "../../../.ssh/id_rsa" with display_path: "config.yaml" “Read config.yaml” Reads SSH private key
Type confusion permissions: "read" (string) instead of permissions: ["read"] (array) “Read access” Parser falls back to wildcard
Missing required fields No tool_id, no resource Generic “Tool needs access” Agent fills in defaults (often over-privileged)
Plugin supply chain Compromised plugin sends crafted payload “Plugin needs API access” Exfiltrates all environment variables

The Fix: Strict Payload Validation Before Prompt

Zero now validates every permission payload before presenting it to the user. If the payload is malformed — missing required fields, wrong data types, unexpected keys, or failed schema validation — Zero rejects it immediately and logs the incident. The user never sees a prompt for a malformed request.

Validation Rules Enforced

// Simplified validation schema (actual implementation in Zero core)
interface PermissionPayload {
  tool_id: string;                    // Required: unique tool identifier
  resource: string;                   // Required: file path, URL, or resource ID
  action: "read" | "write" | "execute"; // Required: single action, not array
  display_path?: string;              // Optional: human-readable path (validated against resource)
  expires_at?: number;                // Optional: Unix timestamp, max 24h
  metadata?: Record<string, unknown>; // Optional: flat object, no nested structures
}

// Validation checks (all must pass):
// 1. All required fields present and non-empty
// 2. action is exactly one of: read, write, execute (no arrays, no extra values)
// 3. resource is a valid path/URL (no null bytes, no protocol confusion)
// 4. If display_path provided, it must resolve to same resource (prevents spoofing)
// 5. expires_at if present: > now, < now + 24h
// 6. metadata if present: flat keys only, values are primitives
// 7. No additional properties beyond schema (strict mode)

The additional_permissions Extensibility Point

The fix specifically targets additional_permissions payloads — the extensibility point where tool plugins declare their permission needs. This is the supply chain attack surface: a malicious or buggy plugin can’t slip through a malformed permission request anymore.

// Plugin manifest declares permissions it needs
{
  "name": "gitlawb-zero-github-plugin",
  "additional_permissions": [
    {
      "tool_id": "github.create_pr",
      "resource": "github.com/{owner}/{repo}/pulls",
      "action": "write",
      "display_path": "Create pull request in {owner}/{repo}"
    }
  ]
}

// At runtime, plugin sends payload for each use
// Zero validates against manifest + schema before prompting

Why This Matters: Permission Systems Are Only As Strong As Their Input Validation

Presenting a malformed prompt to the user and relying on them to notice the discrepancy is not security — it’s theater. Users click “Allow” on permission prompts reflexively; they cannot be expected to audit JSON payloads.

Zero’s fix is the right approach: reject malformed payloads at the system level, before they reach the user. The user should never have to decide whether a malformed permission request is safe, because the system has already decided it’s not.

This kind of security hardening is especially important for agents that run locally with access to your:

  • Filesystem — source code, configs, SSH keys, AWS credentials
  • Network — localhost services, internal APIs, corporate VPN
  • Process execution — shell commands, package installs, deployment scripts
  • Clipboard & keystrokes — everything you copy or type

Zero’s permission system was already well-designed (just-in-time, granular, revocable). Now it’s well-defended too.

Comparison: How Other Agents Handle Permission Validation

Agent Permission Model Payload Validation Prompt Spoofing Protection
Gitlawb Zero Just-in-time, granular Strict schema validation (new) Display path vs resource cross-check
Claude Code Project-level allowlist Basic (tool allowlist only) Limited
Cursor Project-level allowlist Basic Limited
OpenHands Runtime sandbox Schema validation Partial
Goose Tool allowlist None (trusts tool definitions) None
Aider File-level allowlist None None

Zero is unique in validating the runtime payload against a strict schema before every prompt — not just trusting static tool definitions.

Practical Impact for Operators

What Changes for You

  1. No more confusing prompts — Every prompt you see has passed strict validation
  2. Plugin safety — Third-party plugins can’t bypass permission semantics with malformed payloads
  3. Audit trail — Rejected payloads are logged with plugin ID, payload hash, and validation failure reason
  4. Debugging — If a tool stops working, check logs for permission_payload_rejected entries

Configuration

{
  "permissions": {
    "strictValidation": true,
    "logRejectedPayloads": true,
    "maxPayloadSize": 4096,
    "allowedPlugins": ["github", "docker", "k8s", "terraform"]
  }
}

Testing Your Plugins

If you write Zero plugins, test payload validation:

# Validate a plugin's permission manifest
zero plugin validate ./my-plugin/

# Simulate a permission request (dry run)
zero permission test --tool github.create_pr --resource "github.com/owner/repo/pulls" --action write

The smartest developers don’t pick one AI — they use them all. aiFiesta brings 9+ premium models into one chat for $12/mo. Your AI toolkit, simplified. The smartest developers don’t pick one AI — they use them all. aiFiesta brings 9+ premium models into one chat for $12/mo. Your AI toolkit, simplified.

FREE RESOURCE

Get the AI Agent Cheat Sheet

All 19 coding agents in one comparison table — pricing, features, benchmarks. Updated weekly. Delivered to your inbox.

k
kira_bug_hunter
Security & Bug Hunter
Former pen tester. Finds the bugs nobody wants to exist. Skeptical of everything, especially status indicators.

Related articles