Deletion Requests¶
Deletion requests are the mandatory four-eyes workflow for NetBox to Proxmox
DELETE intent. A branch merge containing a DELETE diff must not call Proxmox
destroy. It creates a pending DeletionRequest row instead.
This page is for operators who request, approve, reject, or investigate deletions.
Core Rule¶
Every Proxmox-side DELETE goes through a DeletionRequest.
No merge handler may destroy a VM or LXC. No plan summary may destroy a VM or LXC. No custom view may bypass approval. The only destructive action happens after a pending request is approved and an executor calls the backend deletion route.
Four-Eyes Chain¶
The delete path has five locks:
- Master setting
netbox_to_proxmox_enabled=True. - Typed phrase
allow-edit-and-add-actions. - Branch field
apply_destroy_confirmed=True. - Requester has
intent_delete_vmorintent_delete_lxc. - A separate authorizer has
authorize_deletion_request.
If any lock fails, the deletion does not execute.
Roles¶
- Requester
-
The user who changes a branch and requests a deletion. This user needs the relevant
intent_delete_*permission. - Authorizer
-
The user who reviews and approves or rejects a pending request. This user needs
authorize_deletion_request. - Executor
-
The background job that acts after approval. It uses the metadata snapshot captured at request time.
Requesting A Deletion¶
- Create a branch.
- Set
apply_to_proxmox=True. - Set
apply_destroy_confirmed=True. - Delete the VM or LXC record in the branch.
- Review the plan summary.
- Confirm the plan does not show local blockers.
- Request the merge.
- Merge after normal review.
- Open
/plugins/proxbox/intent/deletion-requests/. - Confirm a pending row exists.
The merge does not destroy the Proxmox object. It records intent and waits for separate authorization.
Request Snapshot¶
The request captures enough data for later execution even if the NetBox object no longer exists:
- VMID.
- Node.
- Kind (
qemuorlxc). - Name.
- Tags.
- CPU.
- Memory.
- Disk data.
- Interface data.
- IP data.
- Custom fields.
- Branch reference where available.
- Requesting user.
- Request timestamp.
The detail page renders the metadata snapshot directly. It does not call external audit services.
Pending Tag¶
When tagging is available, the apply job adds the Proxmox tag
proxbox-pending-deletion.
The tag is a marker only. It is not authorization. The destroy still requires a pending request to be approved by an authorized user.
Approving A Request¶
- Open Plugins > Proxbox > Deletion Requests.
- Filter to
pending. - Open the row.
- Review the metadata snapshot.
- Confirm the requester.
- Confirm the branch.
- Confirm VMID and node.
- Click Approve.
- Type the requested VMID when the form requires it.
- Submit.
- Confirm the row state becomes approved or executing.
- Watch executor status and run UUID.
The approval view rejects self-approval unless
intent_apply_authorization_self_approve_allowed=True.
Rejecting A Request¶
- Open the pending request.
- Click Reject.
- Enter a short reason.
- Submit.
- Confirm the state is rejected.
Rejected rows remain in NetBox for audit. The metadata snapshot stays attached to the row.
Execution¶
After approval, the executor performs the destructive backend call.
The row tracks:
- Current state.
- Authorizer.
- Approval timestamp.
- Execution timestamp.
- Executor run UUID.
- Failure state when execution fails.
The detail page shows the state transition chain so reviewers can see who requested, who approved, and whether an executor ran.
States¶
pending-
Created by an apply job and waiting for authorization.
approved-
Approved by an authorized user and ready for execution.
rejected-
Rejected by an authorized user or policy.
executing-
Executor is currently running.
succeeded-
Backend deletion completed.
failed-
Backend deletion failed or the executor could not complete.
Self-Approval Policy¶
The safe default is no self-approval. A user who requested the delete cannot approve the same request.
Only enable self-approval for a lab or single-operator environment. Production roles should keep request and authorization separated.
RBAC Checklist¶
Requester role:
- View relevant VMs.
- Change branch content.
intent_delete_vmfor QEMU VM deletes.intent_delete_lxcfor LXC deletes.
Authorizer role:
- View deletion requests.
authorize_deletion_request.
Operator role for troubleshooting:
- View apply jobs.
- View deletion requests.
- View backend logs when needed.
Common Errors¶
Self-approval blocked-
A requester attempted to approve their own deletion. Use a different authorized user or intentionally enable the self-approval setting.
permission denied-
The requester lacks
intent_delete_*or the authorizer lacksauthorize_deletion_request. apply_destroy_confirmed not set-
The branch contains DELETE diffs but the branch-level confirmation field is false.
DeletionRequest never appears-
Check the apply job per-VM results. The DELETE may have been skipped before request creation.
executor_run_uuid is empty-
The request has not reached executor execution yet, or execution failed before a run UUID was assigned.
state stays pending-
No authorized user has approved the row.
state stays approved-
Check RQ workers and queue state.
state failed-
Inspect the row, apply job results, backend logs, and Proxmox task output.
Audit Review¶
For an incident review, capture:
- The branch name and ID.
- The apply job run UUID.
- The deletion request ID.
- Requested by.
- Authorizer.
- State transitions.
- Executor run UUID.
- Metadata snapshot.
- Backend log lines for the executor call.
- Proxmox task result where available.
The NetBox row is the starting point for audit. It should be sufficient to show the human approval chain without calling external audit APIs.
Operational Guidance¶
- Keep pending requests low.
- Reject stale requests instead of leaving them pending indefinitely.
- Review metadata before approval, not after.
- Treat VMID mismatch as a stop condition.
- Do not approve a row only because the branch merged.
- Do not remove pending-deletion tags manually unless recovering from a failed workflow.
- Prefer fixing the branch and creating a new request over editing snapshots.