> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opal.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Set the agent kill switch

> **Prototype (AG-297).** Turns the org-level agent kill switch on or off. Admin only.

While it is on, Opal answers every `PreToolUse` hook POST to `/agent-activity` with a `deny` decision, so a cooperating Claude Code client stops running tools.

**It is not a security boundary, and it fails open.** It reaches only clients that are configured to POST to `/agent-activity` and that honour the answer; a client on a non-default base URL, an older build, or with no hook deployed is unaffected. If Opal is unreachable or slow the tool call proceeds, because Claude Code treats a failed `PreToolUse` hook as a non-blocking error by design.

Activation is always time-bound: `duration_minutes` is capped, and an activation that reaches `expires_at` stops denying on its own.



## OpenAPI

````yaml https://app.opal.dev/openapi.yaml put /agent-kill-switch
openapi: 3.1.0
info:
  contact:
    email: hello@opal.dev
    name: Opal Team
    url: https://www.opal.dev/
  description: >-
    The Opal API is a RESTful API that allows you to interact with the Opal
    Security platform programmatically.
  title: Opal API
  version: '1.0'
servers:
  - description: Production
    url: https://api.opal.dev/v1
security: []
tags:
  - name: access-rules
    description: Operations related to access rules
  - name: agent-activity
    description: Operations related to agent activity telemetry
  - name: apps
    description: Operations related to apps
  - name: bundles
    description: Operations related to bundles
  - name: campaigns
    description: Operations related to access review campaigns
  - name: configuration-templates
    description: Operations related to configuration templates
  - name: delegations
    description: Operations related to request reviewer delegations
  - name: event-streams
    description: Operations related to event streaming connections
  - name: events
    description: Operations related to events
  - name: groups
    description: Operations related to groups
  - name: group-bindings
    description: Operations related to group bindings
  - name: idp-group-mappings
    description: Operations related to IDP group mappings
  - name: message-channels
    description: Operations related to message channels
  - name: non-human-identities
    description: Operations related to non-human identities
  - name: on-call-schedules
    description: Operations related to on-call schedules
  - name: opal-queries
    description: Operations related to OpalQuery
  - name: opal-scripts
    description: Operations related to OpalScripts
  - name: owners
    description: Operations related to owners
  - name: requests
    description: Operations related to requests
  - name: resources
    description: Operations related to resources
  - name: role-assignments
    description: >-
      Operations related to role assignments (general grants between an entity
      and a principal)
  - name: paladin
    description: Operations related to Paladin
  - name: sessions
    description: Operations related to sessions
  - name: tags
    description: Operations related to tags
  - name: tokens
    description: Operations related to API tokens
  - name: uars
    description: Operations related to UARs. Deprecated in favor of the `campaigns` API.
  - name: users
    description: Operations related to users
paths:
  /agent-kill-switch:
    put:
      tags:
        - agent-activity
      summary: Set the agent kill switch
      description: >-
        **Prototype (AG-297).** Turns the org-level agent kill switch on or off.
        Admin only.


        While it is on, Opal answers every `PreToolUse` hook POST to
        `/agent-activity` with a `deny` decision, so a cooperating Claude Code
        client stops running tools.


        **It is not a security boundary, and it fails open.** It reaches only
        clients that are configured to POST to `/agent-activity` and that honour
        the answer; a client on a non-default base URL, an older build, or with
        no hook deployed is unaffected. If Opal is unreachable or slow the tool
        call proceeds, because Claude Code treats a failed `PreToolUse` hook as
        a non-blocking error by design.


        Activation is always time-bound: `duration_minutes` is capped, and an
        activation that reaches `expires_at` stops denying on its own.
      operationId: setAgentKillSwitch
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetAgentKillSwitchRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentKillSwitch'
          description: The state of the kill switch after the change.
        '400':
          description: The body was unparseable, or `duration_minutes` was out of range.
        '403':
          description: >-
            The caller is not an admin, or the agent kill switch is not enabled
            for this organization.
      security:
        - BearerAuth: []
components:
  schemas:
    SetAgentKillSwitchRequest:
      description: >-
        # SetAgentKillSwitchRequest Object

        ### Description

        Turns the agent kill switch on or off.


        Setting `active` to `true` while it is already on supersedes the current
        activation

        rather than extending it: the old row keeps its own reason and window as
        part of the

        audit trail, and a new one starts.
      properties:
        active:
          description: >-
            True denies agent tool calls for this organization; false lifts the
            denial.
          type: boolean
        duration_minutes:
          description: >-
            How long the denial lasts, from now. Ignored when `active` is false.
            Capped server-side - a kill switch with no end is how an
            organization discovers months later that its engineers have been
            quietly working around it.
          type: integer
        reason:
          description: >-
            Why. Shown verbatim to the developer whose tool call is denied, so
            write it for them rather than for the audit log - it is the only
            explanation they get.
          type: string
      required:
        - active
      type: object
    AgentKillSwitch:
      description: >-
        # AgentKillSwitch Object

        ### Description

        The org-level agent kill switch, and the activation that is in force or
        last was.


        `active` is what matters; the rest is the record of how it got that way.
        An

        activation is in force only while it has not been deactivated AND
        `expires_at` is

        still in the future, and that is evaluated on every read - so `active`
        can be

        `false` on a row that was never explicitly turned off.


        Everything below `active` describes the LATEST activation whether or not
        it is

        still in force, so an admin reading an inactive switch can still see who
        last

        turned it on and when it ended.
      properties:
        active:
          description: >-
            Whether agent tool calls are being denied right now. This is the
            field to read; it already accounts for expiry.
          type: boolean
        activated_at:
          description: >-
            When the latest activation was turned on. Absent if it never has
            been.
          format: date-time
          type: string
        activated_by_user_id:
          description: >-
            The admin who turned it on. Absent when that user has since been
            hard-deleted - the activation record outlives them deliberately.
          format: uuid
          type: string
        expires_at:
          description: >-
            When the latest activation stops denying on its own. In the past for
            an activation that already ran out.
          format: date-time
          type: string
        deactivated_at:
          description: >-
            When the latest activation was turned off before its expiry, either
            by an admin or by being superseded. Absent when it ended at
            `expires_at`, or has not ended.
          format: date-time
          type: string
        reason:
          description: >-
            The admin's stated reason. Not an internal note - it is shown to the
            developer whose tool call is denied, in their own terminal.
          type: string
      required:
        - active
      type: object
  securitySchemes:
    BearerAuth:
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.