teardown.sh¶
macOS / Linux teardown entry point. Reverses everything setup.sh creates and,
optionally, deprovisions individual Agent User chains by UPN.
Purpose¶
teardown.sh removes the full Agent Identity chain and local state that setup
creates: the Agent User, the Agent Identity service principal, the Blueprint app
registration (and its cascaded BlueprintPrincipal), the Provisioner app
registration, and the local .env, .entrabot-state.json, and OS keystore
entries.
It operates in one of two modes:
- State-based full teardown (default) — reads the resource IDs from
.envand.entrabot-state.jsonand deletes the whole chain those IDs describe. - Targeted teardown — when one or more
--agent-user-upnvalues are given, it delegates each UPN todeprovision_entra_agent_identity.pyand skips the state-based deletes.
Cloud (Azure Blob) storage is never deleted by this script. See Effects and Safety below.
Requirements¶
- macOS or Linux with
bash. - Azure CLI (
az) signed in (az login). It is used to discover and delete the Provisioner app and to delete the Agent User, which are ordinary directory objects. - The project virtual environment at
.venvwith provisioning dependencies installed (pip install -e ".[dev]"). The script uses.venv/bin/python3to mint a Provisioner certificate token and to call the Microsoft Graph beta endpoints that delete the Agent Identity and Blueprint. python3andkeyringfor reading state and clearing keystore entries.
If the Provisioner certificate token cannot be acquired, the script continues but cannot delete the Agent Identity or Blueprint (see Common failures).
Usage¶
# Full teardown of the chain described by local state
./scripts/teardown.sh
# Preview only — resolve and print, delete nothing
./scripts/teardown.sh --dry-run
# Skip the interactive confirmation prompt
./scripts/teardown.sh --yes
# Targeted teardown of one or more Agent User chains by UPN
./scripts/teardown.sh --agent-user-upn=agent-sample@contoso.onmicrosoft.com
./scripts/teardown.sh --agent-user-upn=agent-a@contoso.onmicrosoft.com,agent-b@contoso.onmicrosoft.com
# Preserve the shared Provisioner app or local state
./scripts/teardown.sh --preserve-provisioner
./scripts/teardown.sh --preserve-local-state
Options¶
| Option | Default | Effect |
|---|---|---|
--agent-user-upn=UPN |
none | Target a specific Agent User UPN for deprovisioning instead of the state-based chain. May be repeated or comma-separated. Switches the run to targeted mode. |
--dry-run |
off | Resolve and print what would be deleted without deleting anything in the tenant or on disk. In targeted mode the flag is passed through to the deprovision helper. |
--yes, -y |
off | Skip the interactive Are you sure? confirmation prompt. |
--delete-cloud-storage |
off | Reserved and intentionally not implemented. Supplying it exits with an error (see Safety). |
--preserve-provisioner |
off | Do not delete the shared Provisioner app. Intended for targeted, smoke-test teardowns that reuse the Provisioner. |
--preserve-local-state |
off | Do not remove .env, .entrabot-state.json, or local keystore entries. Intended for wrapper-managed test runs. |
--help, -h |
— | Print usage and exit. |
An unrecognized argument prints an error to stderr followed by the usage text.
Effects¶
When there is nothing to remove — no Entra resources referenced by local state,
no Provisioner app discoverable by name, and no local state files — the script
prints Nothing to clean up. and exits without prompting.
Otherwise it prints the resources it is about to delete and, unless --dry-run
or --yes is set, prompts for confirmation before proceeding.
Deletion order (state-based full teardown). Children are removed before parents:
- Agent User — deleted with
az ad user delete(an Agent User is an ordinary directory user, so the Azure CLI token is accepted here). - Agent Identity service principal — deleted via
DELETE /beta/servicePrincipals/{id}using the Provisioner certificate token. - Blueprint application — deleted via
DELETE /beta/applications/{id}using the Provisioner certificate token. This cascade also removes theBlueprintPrincipal. - Provisioner app — deleted last (it is needed for steps 2–3), by display
name, with
az ad app delete, unless--preserve-provisioneris set. - Local state — unless
--preserve-local-stateis set: clears the Blueprint private key and legacy secrets from the OS keystore (serviceentrabot), then removes.envand.entrabot-state.json.
Targeted teardown. Each --agent-user-upn is handed to
deprovision_entra_agent_identity.py,
which removes the Agent User's directly-assigned licenses, the Agent User, the
Agent Identity, and the Blueprint for that UPN. After a targeted run the
state-based deletes in steps 1–3 are skipped; step 4 (Provisioner) and step 5
(local state) still run unless the corresponding --preserve-* flag is set.
Cloud storage. Any Azure Blob container, storage account, or resource group
used for cloud-hosted memory is left untouched. Remove it separately with
deprovision_blob_storage.py.
Safety¶
This permanently deletes Entra identities
A full teardown deletes the Agent User, Agent Identity, and Blueprint from
the tenant. There is no undo. Run --dry-run first and confirm the printed
resource IDs are the ones you intend to remove.
--delete-cloud-storageis refused. The switch is reserved but not implemented: passing it prints an error explaining that cloud storage is not deleted here and exits non-zero, so no partial storage teardown can occur. Back up any cloud memory, then delete containers or accounts manually or withdeprovision_blob_storage.py.- The state-based full teardown does not check for shared Blueprints. Steps
2–3 delete the Agent Identity and Blueprint named in local state
unconditionally. If several Agent Identities share one Blueprint, a full
teardown removes that Blueprint out from under the others. To delete a single
chain while leaving a shared Blueprint intact, use targeted mode
(
--agent-user-upn), which delegates todeprovision_entra_agent_identity.pyand refuses to delete a Blueprint still referenced by other Agent Identities. - The confirmation prompt defaults to No; any answer other than
y/Yaborts without changes.
Common failures¶
- No Provisioner token — Agent Identity / Blueprint not deleted. If the
.venvis missing or the Provisioner certificate is unavailable, the script warns and cannot delete the Agent Identity or Blueprint: the Agent Identity beta APIs reject Azure CLI tokens (which carry theDirectory.AccessAsUser.Allscope) with a hard403. The Agent Identity and Blueprint then survive as orphans. Delete them afterward withcleanup-orphans.shor in the Entra admin portal. Not logged in. Provisioner discovery and Agent User deletion needaz login.- Resource already deleted. A
404from a delete is treated as already-gone and reported as a warning, not a failure.
Exit behavior¶
0— success; also returned for--help,--dry-run, aNothing to clean upno-op, an aborted confirmation, and a--preserve-local-stateearly exit.1— a targeted--agent-user-upnteardown failed.2—--delete-cloud-storagewas supplied (refused).
Because the script runs under set -euo pipefail, an unexpected error in a
non-tolerated step also aborts with a non-zero status.
Related commands¶
deprovision_entra_agent_identity.py— targeted, shared-Blueprint-safe teardown of one UPN.cleanup-orphans.sh— delete Agent Identity / Blueprint orphans left after a token failure.teardown-windows.ps1— local-only teardown on Windows.deprovision_blob_storage.py— remove cloud-memory storage.setup.sh— the provisioning entry point this reverses.- Teardown reference index
- Identity Lifecycle and Deprovisioning