# SSH Filtering

SSH access policies allow you to control access to SSH resources based on provider, destination, group, region, parent resource, and sudo privileges. You can also configure **break glass** access, which grants unrestricted SSH access to all resources for emergency scenarios.

{% hint style="info" %}
Before configuring SSH access policies, ensure you have installed the SSH integration. See [SSH integration setup](/integrations/resource-integrations/ssh.md) for details.
{% endhint %}

## SSH access types

The SSH integration supports four access types. Each access type represents a different scope of resources you can grant access to:

| Access type | Description                                                                                                  |
| ----------- | ------------------------------------------------------------------------------------------------------------ |
| `session`   | Access to an individual compute instance. This is the most granular level of SSH access.                     |
| `group`     | Access to a tagged collection of instances within a service provider. A group may contain one or more nodes. |
| `parent`    | Access to all instances within a hierarchical unit — an AWS account, GCP project, or Azure subscription.     |
| `all`       | A global access request that grants access to all SSH resources. This is **break glass** access.             |

Outside of `session`, the other access types control access to collections of instances, which may include one or more nodes at a time.

You can scope an access policy to a specific access type using the `accessType` field:

```yaml
resource:
  type: integration
  service: ssh
  accessType: session
```

If you omit `accessType` or set it to `any`, the rule applies to all SSH access types.

## Available filters

SSH access policies support six filter types:

| Filter        | Key                                    | Description                                                                                                                                                                                                    |
| ------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`    | `id`                                   | Cloud provider managing the instance. Must be `aws`, `azure`, `gcloud`, or `self-hosted`.                                                                                                                      |
| `destination` | `arn`, `name`, or `full-resource-name` | Instance identifier. Use `arn` for AWS instances, `full-resource-name` for GCP instances, or `name` for instance name across providers. To list available instance names, run `p0 ls ssh session destination`. |
| `group`       | `name`                                 | SSH group name — the tagged collection of instances within a provider.                                                                                                                                         |
| `parent`      | `id`                                   | Parent resource identifier. Use a GCP project name, AWS account ID, or Azure subscription ID.                                                                                                                  |
| `region`      | `id`                                   | AWS region, GCP zone, or Azure region.                                                                                                                                                                         |
| `sudo`        | *(boolean filter)*                     | Whether the request includes sudo privileges. When set, you can control who can approve or deny sudo access.                                                                                                   |

### Filter rule structure

```yaml
resource:
  type: integration
  service: ssh
  filters:
    <filter-name>:
      effect: keep|remove|removeAll
      key: <property>
      pattern: <regex pattern>
```

Each filter has three properties:

* **effect** — How the filter is applied:
  * `keep` — Retain resources that match the pattern
  * `remove` — Retain resources that do *not* match the pattern
  * `removeAll` — Disable this filter type entirely
* **key** — The property to match against
* **pattern** — A regex pattern to match (uses the [JavaScript regex dialect](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions))

{% hint style="info" %}
Patterns are unanchored. Use line-start (`^`) and line-end (`$`) markers to anchor patterns.
{% endhint %}

### Sudo filter

The `sudo` filter uses a boolean format rather than a regex pattern:

```yaml
resource:
  type: integration
  service: ssh
  filters:
    sudo:
      effect: keep
      value: true
```

## Filter examples

### Restrict SSH access to a specific cloud provider

Allow SSH requests only for AWS-managed instances:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    filters:
      provider:
        effect: keep
        key: id
        pattern: ^aws$
  approval:
    - type: p0
```

### Restrict SSH access to a specific group

Allow SSH access only to instances in the "web-servers" group:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    accessType: group
    filters:
      group:
        effect: keep
        key: name
        pattern: ^web-servers$
  approval:
    - type: p0
```

### Restrict SSH access by AWS account

Allow SSH access only to instances in a specific AWS account:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    filters:
      parent:
        effect: keep
        key: id
        pattern: ^123456789012$
  approval:
    - type: group
      id: sre-team@yourco.com
      label: SRE Team
      directory: workspace
```

### Deny sudo access

Deny all SSH requests that include sudo privileges:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    filters:
      sudo:
        effect: keep
        value: true
  approval:
    - type: deny
```

### Restrict SSH to a specific region

Allow SSH access only to instances in `us-east-1`:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    filters:
      region:
        effect: keep
        key: id
        pattern: ^us-east-1$
  approval:
    - type: p0
```

## Break glass access

Break glass provides emergency SSH access to **all** resources covered by your access policies. It's designed for incident response — when there is an outage and an engineer needs broad access to production systems to troubleshoot. Instead of requesting access to each instance individually and waiting for approval, they can use break glass access.

### How break glass works

1. A user requests SSH break glass access (access type `all`) via the CLI: `p0 request ssh all`
2. P0 identifies all access policies where the user is a matching requestor **and** the policy has a `breakGlassApprover` configured
3. P0 creates a **separate request for each matching access policy**. If you are a requestor in five different access policies, P0 creates five requests, and each must be individually approved.
4. Each request is routed to the break glass approver(s) configured on that policy
5. Once a break glass request for an access policy is approved, individual session requests to instances covered by that policy are **auto-approved** — you still make the individual session requests, but they no longer require manual approval
6. If no access policies with `breakGlassApprover` match the user, the request is rejected with: *"No access policy allows break-glass access"*

{% hint style="warning" %}
Break glass access grants broad SSH access. Restrict the `breakGlassApprover` option to a small, trusted group of approvers — for example, a network operations center (NOC) staffed 24/7.
{% endhint %}

{% hint style="info" %}
Break glass doesn't provision access to all instances at once. Instead, it pre-approves later individual session requests. You request specific instances as needed, and those requests are automatically approved based on the break glass grant.
{% endhint %}

### Configuring break glass

Break glass requires **two** types of access policies working together:

1. A **regular rule** with a standard approver — this handles day-to-day access to individual instances
2. A **break glass rule** with a `breakGlassApprover` — this handles the emergency `all` access request

Both rules must exist. The regular rule defines which resources are accessible and who approves normal requests. The break glass rule defines who can approve the emergency override.

{% hint style="warning" %}
If an access policy uses `accessType: session` filters, break glass requests (`accessType: all`) do not match that policy. Ensure your break glass policy either omits `accessType` or explicitly sets `accessType: all`.
{% endhint %}

#### Example: complete break glass configuration

```yaml
# Rule 1: Regular SSH access to customer stack
# Day-to-day access, approved by engineering managers
- requestor:
    type: group
    id: engineers@yourco.com
    label: Engineers
    directory: workspace
  resource:
    type: integration
    service: ssh
    accessType: session
    filters:
      destination:
        effect: keep
        key: name
        pattern: ^customer-node
  approval:
    - type: group
      id: eng-managers@yourco.com
      label: Engineering Managers
      directory: workspace

# Rule 2: Break glass access to customer stack
# Emergency access, approved by NOC team
- requestor:
    type: group
    id: engineers@yourco.com
    label: Engineers
    directory: workspace
  resource:
    type: integration
    service: ssh
    accessType: all
  approval:
    - type: group
      id: noc-team@yourco.com
      label: NOC Team
      directory: workspace
      options: { breakGlassApprover: true }
```

In this example:

* **Rule 1** grants engineers access to specific instances matching `customer-node*`, approved by engineering managers
* **Rule 2** grants engineers break glass access to all SSH resources, approved by the NOC team (staffed 24/7)
* When an engineer runs `p0 request ssh all`, P0 creates a break glass request routed to the NOC team
* Once the NOC team approves, the engineer can request individual sessions (for example, `customer-node-1`) and those requests are auto-approved

### Break glass with PagerDuty escalation

You can combine break glass with PagerDuty escalation for incident-driven emergency access:

```yaml
- requestor:
    type: any
  resource:
    type: integration
    service: ssh
    accessType: all
  approval:
    - type: escalation
      integration: pagerduty
      options: { breakGlassApprover: true, requireReason: true }
      services: [PSJXXXG]
```

In this example:

* Any user can request break glass SSH access
* The request requires a reason
* PagerDuty routes the request through the configured escalation policy
* Only the on-call responder from the configured PagerDuty service can approve

### Multiple access policies and break glass

When you are a requestor in multiple access policies, a break glass request creates a **separate request for each matching policy**. Each request:

* Routes the request to the break glass approver configured on that specific rule
* Must be individually approved
* Grants auto-approval for instances covered by that rule only

This means you can have different break glass approvers for different sets of resources. For example, the NOC team approves break glass for production systems, while the SRE team approves break glass for staging systems.

### Separating break glass from regular approvals

P0 routes requests to the correct approvers based on whether `breakGlassApprover` is set:

* Regular SSH requests (`session`, `group`, `parent`) are routed to approvers on rules **without** `breakGlassApprover`
* Break glass SSH requests (`all`) are routed to approvers on rules **with** `breakGlassApprover: true`

This separation ensures that break glass approvals require explicit authorization from designated approvers, while regular access follows the standard approval flow.

### Supported approval types for break glass

The `breakGlassApprover` option is available on the following approval types:

| Approval type       | Description                                        |
| ------------------- | -------------------------------------------------- |
| `p0`                | P0 security reviewers                              |
| `group`             | Members of a directory group                       |
| `escalation`        | PagerDuty escalation                               |
| `requestor-profile` | The requestor's manager from the directory profile |

{% hint style="info" %}
The `auto`, `persistent`, and `deny` approval types do not support the `breakGlassApprover` option.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.p0.dev/access-management/just-in-time-access/request-routing/ssh-filtering.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
