azctx

command module
v1.7.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2026 License: MIT Imports: 5 Imported by: 0

README ΒΆ

azctx - Azure-CLI Context Switcher

azctx is a command-line tool designed to streamline the management of Azure tenant and subscription contexts. It provides an intuitive fuzzy-finder interface for switching between Azure subscriptions and tenants, making it easier to work with multiple Azure environments.

[!NOTE] Unlike plain az account set, azctx makes per-shell isolation the default mode of operation: switching context never mutates ~/.azure. See Origins.

Features

  • 🐚 Per-shell isolated contexts β€” each azctx invocation copies ~/.azure to a private tempdir, sets AZURE_CONFIG_DIR, and drops you into a subshell; the master ~/.azure is never touched
  • πŸ” Real fzf picker, embedded β€” inline (no full-screen takeover), themed by your FZF_DEFAULT_OPTS and any fzf options via config
  • ⚑ Quick context switching between subscriptions
  • 🏷️ Short aliases for subscriptions, in the picker and --subscription
  • πŸ”„ Easy switching to previous context (similar to cd -)
  • 🎯 Tenant-first selection mode
  • πŸ”§ Configurable logging levels

Prerequisites

  • azure-cli >= 2.22.1 (azctx manages its profile; the fuzzy finder itself is built in)
  • go >= 1.26 (building from source only)

Installation

Linux and macOS only β€” the per-shell isolation relies on Unix process semantics ($SHELL, signals), so there are no Windows builds.

Brew (macOS/Linux)
brew install iul1an/azctx/azctx
Arch Linux
# from a checkout: builds a package from the latest release tag and
# installs it with pacman (binary, completions, license)
make arch-install
Download Prebuilt Binary

Download the latest release from the releases page and add it to your PATH.

Install from Source
go install github.com/iul1an/azctx@latest
# or from a checkout (default /usr/local/bin; override e.g. PREFIX=$HOME for ~/bin):
make install PREFIX=$HOME
Shell Completion

Completions for bash, zsh, fish, and powershell are built in:

# zsh: write into any directory on your $fpath
azctx completion zsh > ~/.zsh/completions/_azctx

# bash
azctx completion bash > /etc/bash_completion.d/azctx

Flag values complete too: --subscription <Tab> offers the live subscription names from your active profile, and --log-level <Tab> its four levels. The generated script delegates to the binary at runtime, so new subcommands and flags are picked up without regenerating the file.

Usage

Basic Subscription Switching
# Pick a subscription and drop into a subshell scoped to it.
# ~/.azure is copied to a tempdir and AZURE_CONFIG_DIR points at the copy,
# so the pick never mutates your master config.
azctx

# Inside the isolated shell:
echo $AZURE_CONFIG_DIR   # /tmp/azctx.XXXXXXX
az account show          # shows the picked subscription

# An isolated shell is bound to its subscription for its whole lifetime:
# re-running azctx inside one is refused (it couldn't update the shell's
# AZCTX_SUBSCRIPTION). Exit the shell and re-run azctx, or use azctx exec.

# Exit the subshell; the tempdir is cleaned up automatically.
exit

# Switch to previous subscription context
azctx -

# Clear the default subscription in the master ~/.azure (no picker,
# no subshell). Refused inside an isolated shell.
azctx --unset

# Start from a completely empty Azure config: nothing copied from
# ~/.azure, no picker. az behaves as never-logged-in inside; an
# `az login` there vanishes with the shell. Also works with exec.
azctx --fresh
azctx exec --fresh -- az login --use-device-code

# List subscriptions ('*' = default) and isolated contexts (config
# dir, subscription, owning PID, age; '*' = current shell's context).
# --json emits both as indented JSON.
azctx list

# Show the current context as indented JSON β€” subscription, tenant,
# PID, env consistency. The `isolated` field tells you whether you are
# inside an isolated shell.
azctx status

Every azctx invocation garbage-collects orphaned contexts: each tempdir records its owning process, and dirs whose owner is gone (e.g. after a SIGKILL) are removed automatically on the next run.

Tenant-First Selection
# Select tenant before choosing subscription
azctx --by-tenant

The profile carries no tenant names, so the picker labels tenants with the signed-in account. Name them yourself in the config, keyed by tenant ID:

tenants:
  33333333-3333-3333-3333-333333333333: "Contoso"
Exec Mode
# Pick a subscription, run a single command in the isolated context,
# then clean up β€” similar to aws-vault exec. The command's exit code
# is propagated.
azctx exec -- kubectl get pods
azctx exec --by-tenant -- kubie ctx my-aks-cluster

# Skip the picker entirely with --subscription (alias, name, or ID;
# names and aliases are case-insensitive). Also works on bare azctx.
azctx exec --subscription "My Subscription" -- kubectl get pods
# 'prod' below is an alias, see Subscription Aliases
azctx exec --subscription prod -- az aks list --query '[].name' -o tsv

# With no command, exec drops into an isolated subshell instead of
# running something and exiting β€” so `exec --subscription` is a
# non-interactive way into a shell, skipping the picker.
azctx exec --subscription "My Subscription"

Like bare azctx, exec is refused inside an isolated shell: exit it first and re-run. Nesting contexts is confusing and buys nothing.

Subscription Aliases

Optional short names for subscriptions, defined in the config file as an alias to a subscription ID or name:

aliases:
  prod: 11111111-2222-3333-4444-555555555555
  dev: "My Dev Subscription"

Use them anywhere --subscription is accepted; <Tab> completes them.

azctx --subscription prod
azctx exec --subscription dev -- az aks list --query '[].name' -o tsv

Aliases are case-insensitive, appear in the picker as My Prod Subscription [prod] (1111-…), and show up in azctx list and azctx status. An alias takes precedence over a subscription of the same name, and one pointing at nothing is an error rather than a fallback.

In-Place Mode
# Mutate the master ~/.azure directly: no tempdir
# copy, no subshell. Refused inside an isolated shell like bare azctx.
azctx --in-place

Notes on isolation:

  • The subshell is $SHELL (fallback /bin/zsh).
  • The spawned shell/command gets AZCTX_SUBSCRIPTION set to the picked subscription's name (like aws-vault's AWS_VAULT), handy for prompts and wrapper scripts. It is always accurate because a shell's subscription is immutable β€” re-picking inside an isolated shell is refused, with no override.
  • Each isolated context gets its own copy of the token cache. If tokens expire, az login inside the subshell only affects that context.
  • kubelogin/kubectl honor AZURE_CONFIG_DIR, so AKS access works inside the isolated shell.
  • az telemetry is off inside contexts (AZURE_CORE_COLLECT_TELEMETRY=0): its uploader outlives the command and would recreate the context dir after cleanup.

Configuration

Configuration is stored in ~/.azctx.yml, or wherever AZCTX_CONFIG_FILE points (any extension, parsed as YAML; naming a file that does not exist is an error). Every flag can be set there (precedence: flag > AZCTX_* environment variable > config file):

# Log level: debug, info, warn, error
log-level: info

# Always pick the tenant before the subscription
by-tenant: false

# Always select this subscription (alias, name, or ID) β€” disables the picker
#subscription: "My Subscription"

# Names for tenants in the --by-tenant picker, keyed by tenant ID
#tenants:
#  33333333-3333-3333-3333-333333333333: "Contoso"

# Short aliases for subscriptions (value is a subscription ID or name)
#aliases:
#  prod: 11111111-2222-3333-4444-555555555555
#  dev: "My Dev Subscription"

# Always start from an empty config (ephemeral-by-default workflow)
#fresh: false

# Suppress the "switched context to" confirmation (also -q on the CLI)
#quiet: false

# Careful with these two as persistent settings:
# in-place: true makes bare azctx mutate ~/.azure directly;
# unset: true makes every bare azctx run clear the default and exit.
#in-place: false
#unset: false

# Picker look and feel: the picker is real fzf embedded as a library, so
# it accepts any fzf options (defaults: --height=~40% --layout=reverse).
# FZF_DEFAULT_OPTS is honored too, so an existing fzf theme just works.
#picker:
#  options: ["--height=~60%", "--border=rounded", "--prompt=azctx> "]
#  preview: false   # true shows details for the highlighted entry:
#                   # subscription fields, or a tenant's subscriptions

You can also set configuration via environment variables:

  • AZCTX_LOG_LEVEL: Set logging level
  • AZCTX_BY_TENANT: Enable tenant-first selection mode
  • AZCTX_CONFIG_FILE: Use this config file instead of ~/.azctx.yml
  • AZCTX_SUBSCRIPTION: Same as --subscription, aliases included. Note the dual role: azctx also exports this into isolated shells, which is what makes nested azctx exec inherit the shell's subscription.

Origins

azctx began as a fork of riweston/aztx by Richard Weston (MIT) and retains its full git history. The fuzzy-finder picker and the azureProfile.json handling descend from that project; the per-shell isolation model, exec/list/status, --fresh, the subscription-binding semantics, and orphaned-context GC are original to azctx. Unlike the original project, azctx does not support Windows: the isolation model is built on Unix process semantics ($SHELL, signals), so only Linux and macOS binaries are published. azctx is not affiliated with or endorsed by the original author.

Contributing

This is an opinionated tool; issues and PRs are welcome, but features that reintroduce mutation of ~/.azure as a default won't be accepted.

License

This project is licensed under the MIT License - see the LICENSE file for details, which carries both the original author's copyright and this project's.

Documentation ΒΆ

Overview ΒΆ

Copyright Β© 2024 Richard Weston

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Directories ΒΆ

Path Synopsis
pkg
errors
Package errors provides a centralized error handling system for the azctx application.
Package errors provides a centralized error handling system for the azctx application.
finder
Package finder provides utilities for finding and selecting items using fuzzy search and ID-based lookups.
Package finder provides utilities for finding and selecting items using fuzzy search and ID-based lookups.
isolation
Package isolation implements per-shell Azure config isolation.
Package isolation implements per-shell Azure config isolation.
profile
Package profile provides interfaces and implementations for managing Azure profiles, including tenant and subscription management, configuration storage, and logging.
Package profile provides interfaces and implementations for managing Azure profiles, including tenant and subscription management, configuration storage, and logging.
state
Package state persists azctx's context-switch history.
Package state persists azctx's context-switch history.
types
Package types provides the core data structures and models used throughout the azctx application.
Package types provides the core data structures and models used throughout the azctx application.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL