---
title: "Set the project's vault policy (owner + step-up)"
method: PATCH
path: "/vaults/v1/{vault_id}/policy"
tags: ["vault"]
---

# Set the project's vault policy (owner + step-up)

`PATCH /vaults/v1/{vault_id}/policy`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/vaults/v1/{vault_id}/policy`
- Auth: one of:
  - API key in header `SIGN-IN-WITH-X`
  - HTTP bearer

Owner + step-up (`gitvault.policy.manage`). The ONLY path to `grandfathered` — the state in which deploys activate WITHOUT a vaulted capture. Audited, and it leaves a persistent warning on the vault record (and in `run402 doctor`) until the policy is set back to `required`. Idempotent: setting the policy it already has returns `changed: false` and writes no audit row. This is also the documented second exit from `409 VAULT_CLIENT_UPGRADE_REQUIRED` — the refusal a pre-vault client meets on `POST /apply/v1/plans/{plan_id}/commit` against a `required` project carries a `grandfather_policy` next_action pointing here (`requires_approval: true`).

## Path parameters

- `vault_id` string, required

## Headers

- `SIGN-IN-WITH-X` string, required

## Request body

- object
  - `vault_policy` 'required' | 'grandfathered', required
  - `reason` string

## Response `200`

Policy state after the call

- object
  - `repo_id` string
  - `project_id` string
  - `vault_policy` 'required' | 'grandfathered'
  - `vault_policy_version` string
  - `vault_policy_changed_at` string, date-time, nullable
  - `changed` boolean
  - `warnings` object[]

## Other responses

- `400`: VALIDATION_FAILED
- `403`: VAULT_ACCESS_DENIED (the `gitvault.policy.manage` check collapses into the vault's one authorize-before-reveal envelope) / STEP_UP_REQUIRED (an owner without a fresh factor for this op class)

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
