Skip to content

Proper device decommissioning with matter decommission #46

@p0fi

Description

@p0fi

Problem

matter fabric remove @1 only deletes the device from the local store — the device itself is never notified and keeps its fabric credentials. This means:

  • The device still thinks it belongs to our fabric and won't enter commissioning mode for re-pairing.
  • A factory reset on the device is required before it can be commissioned again.
  • The equivalent chip-tool command (chip-tool pairing unpair 1) sends RemoveFabric over CASE before deleting locally.

Proposed Solution

Add a top-level matter decommission command that mirrors matter commission:

matter decommission @1

What it should do

  1. Establish a CASE session to the device (reuse daemon session if available).
  2. Determine the fabric index — read the device's OperationalCredentials.Fabrics attribute to find the entry matching our fabric ID, then extract its FabricIndex.
  3. Send RemoveFabric (0x0A) on the OperationalCredentials cluster (endpoint 0) with the resolved fabric index.
  4. On success — delete the node from the local store and evict the cached CASE session.
  5. Print confirmation — e.g. Decommissioned "Kitchen Light" (@1) — device fabric data removed.

Clarify fabric remove as local-only

Make the behavioral difference explicit:

matter fabric remove @1          # local-only: deletes from store, device is NOT notified
matter decommission @1           # proper decommission: sends RemoveFabric, then deletes from store

Consider adding a warning to fabric remove output: "Note: the device was not notified. Use matter decommission to fully remove."

Edge cases

  • Device unreachable — prompt the user: "Device is not responding. Remove from local store anyway? (y/N)". With --force, skip the prompt and delete locally.
  • RemoveFabric rejected — the device may return STATUS_CODE_INVALID_COMMAND if the fabric index is wrong. Surface the error clearly with a suggestion to retry.
  • Last fabric on device — after RemoveFabric, the device re-enters commissioning mode automatically (per spec). No special handling needed, but mention it in the output.

Flags

Flag Short Description
--force -f Remove from local store even if the device is unreachable

Relevant Code

File What it does
cli/fabric.go:190-247 Current fabric remove — local-only delete, good template
cli/device.go:112-126 deleteNode() — routes through daemon or direct store
cli/cluster.go:603-696 invokeCommand() — generic cluster command invocation
internal/clusters/operationalcredentials/cluster.go:35,138-140 CmdRemoveFabric (0x0A) and RemoveFabricRequest — defined but never invoked
internal/secure/case.go:554-618 EstablishCASE() — needed to authenticate before RemoveFabric
internal/daemon/server.go:340-356 handleDeleteNode() — evicts cached session on delete

Out of Scope

  • Bulk decommission (all devices at once) — fabric reset covers the local side; bulk RemoveFabric can come later.
  • Removing our fabric from a device we don't control (requires admin privileges on that device's fabric).

Metadata

Metadata

Assignees

Labels

cliCobra commands, flags, help, output formattingcommissioningPASE/CASE, BLE, on-network, attestationfeatureWholly new capability

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions