Skip to content

zenovalabs/PassCycler

Repository files navigation

PassCycler

PassCycler detects break-glass credential exposure in Cisco IOS XE and NX-OS environments and drives safe password rotation workflows through Vault and Ansible.

PassCycler

What It Is

PassCycler is a three-container workflow:

  • vault: stores group-based break-glass credentials and password policies
  • syslog: receives network syslog telemetry from IOS XE and NX-OS
  • orchestrator: correlates Vault exposure with syslog login usage and triggers Ansible rotation

For live log viewing, the runtime stack also includes a lightweight browser viewer on port 8228 that exposes tailed network.log and vault.log streams.

Vault also exposes a small access model for the demo:

  • Administrator: manages PassCycler policies, auth bindings, and secrets
  • Ansible Password Reader: reads the initial bootstrap password by username
  • Ansible Password Cycler: reads and rotates group secrets plus device aliases
  • Operator 1: reads only the Vault device path for devnet-cat8kv
  • Operator 2: reads only the Vault device path for devnet-n9k

The approved trigger model is:

  1. a secret read in Vault moves the group into armed state,
  2. each successful local login seen in syslog extends the login timeout,
  3. rotation happens when the login timeout expires after the last observed login, or
  4. if no login ever appears, rotation happens on the dead timeout.

The current default timeouts are 5 min after the last observed login and 10 min after disclosure when no login is observed.

Rotation success is confirmed only after a post-change verification login:

  1. PassCycler reads the current password from Vault.
  2. It uses that current password to log in to the device and apply the new password.
  3. It opens a fresh session with the new password to verify that the change really worked.
  4. Only after that verification succeeds does it write the new password back to Vault, where the old value remains in KV version history.
  5. If post-change verification fails, the incident is marked failed and the orchestrator emits a failure event to syslog.

Repository Layout

  • docs/ARCHITECTURE.md explains the system boundaries and runtime shape.
  • DEVELOPMENT.md covers local setup and test execution.
  • OPERATIONS.md covers day-to-day operation and failure handling.
  • docs/DEPLOYMENT_VARIANTS.md defines the supported deployment models.
  • docs/DEVBOX_DEPLOYMENT.md captures the preferred DevNet sandbox deployment model on 10.10.20.50.
  • docs/DEVBOX_RUNBOOK.md is the exact bootstrap and runtime procedure for the DevNet sandbox on the DevBox.
  • docs/OWN_INFRA_RUNBOOK.md is the exact bootstrap and runtime procedure for the own-infrastructure variant.
  • AGENTS.md documents collaboration rules for automated workers.
  • docs/superpowers/specs/2026-04-20-passcycler-design.md is the current approved design basis.

Current Scope

This repository is being scaffolded in stages. The current foundation includes:

  • standard project documentation,
  • packaging metadata and test scaffolding,
  • Docker Compose runtime skeleton,
  • file-backed runtime configuration in config/passcycler.yml,
  • Vault bootstrap assets,
  • IOS XE and NX-OS Ansible bootstrap and rotation playbooks,
  • a tested Python incident/state foundation,
  • a polling orchestrator loop that tails Vault audit and syslog files,
  • seeded Vault paths for canonical group secrets, bootstrap lookup by username, and per-device operator aliases.

Verification

Current local verification:

  • python3 -m pytest tests/test_docs_structure.py tests/test_stack_layout.py tests/test_ansible_files.py tests/test_passwords.py tests/test_events.py tests/test_incident_engine.py -v
  • python3 -m pytest tests/test_rotation.py -v
  • python3 -m ruff check src tests
  • python3 -m mypy src/passcycler
  • PYTHONPYCACHEPREFIX=/tmp/passcycler-pyc python3 -m compileall src

DevNet Demo

The primary demo target is a mixed Cisco DevNet Sandbox lab:

  • devnet-cat8kv on 10.10.20.48 for IOS XE
  • devnet-n9k on 10.10.20.40 for NX-OS

Connectivity prerequisites for the published demo are:

  • reserve the sandbox via Cisco DevNet Sandbox; Cisco DevNet login supports GitHub, Cisco ID, Google, and Webex accounts
  • use the specific sandbox IOS XE on Cat8kv: IOS XE on Cat8kv
  • connect with Cisco Secure Client 5 or OpenConnect
  • use ansible/inventory.devnet.bootstrap.yml as a template for sandbox bootstrap usernames and passwords from your reservation
  • use ansible/inventory.devnet.yml as a template for steady-state rotation with your current break-glass accounts
  • for the sandbox deployment model, prefer running vault + syslog + orchestrator directly on the reachable DevBox at 10.10.20.50; this DevBox-oriented configuration was prepared for the IOS XE on Cat8kv sandbox; see docs/DEVBOX_DEPLOYMENT.md
  • for the sandbox workflow, clone the repository directly on the DevBox and run both switch bootstrap and Docker deployment there; see docs/DEVBOX_RUNBOOK.md
  • for the initial break-glass password on the devices, use PASSCYCLER_INITIAL_IOSXE_PASSWORD and PASSCYCLER_INITIAL_NXOS_PASSWORD in .env.devbox; the DevBox bootstrap helper applies those same values to the devices and Vault
  • for easy repeatable updates on the DevBox, use scripts/deploy_devbox.sh
  • use scripts/devnet_syslog_relay.py only as a local fallback diagnostic helper when the stack is still running on the laptop

This public release ships placeholder DevNet inventory files in ansible/inventory.devnet.bootstrap.yml and ansible/inventory.devnet.yml. Replace those placeholders with the credentials from your current reservation or lab before testing. Vault tokens and any non-public credentials must stay out of git.

For the exact sandbox procedure, use docs/DEVBOX_RUNBOOK.md.

Important bootstrap constraint:

  • PassCycler must preserve the published static sandbox usernames already present on the devices.
  • The bootstrap playbooks only add and maintain the PassCycler break-glass account plus related logging and AAA settings.

Supported Deployment Models

PassCycler maintains two supported deployment variants:

Compose entrypoints:

  • DevNet sandbox / DevBox: docker compose --env-file .env.devbox.example -f docker-compose.yml -f docker-compose.devbox.yml up -d
  • Own infrastructure: docker compose --env-file .env.local.example -f docker-compose.yml -f docker-compose.local.yml up -d

Published UI ports:

  • Vault UI/API: 8200/tcp
  • Syslog viewer: 8228/tcp

Easy update helpers:

The DevBox helper prints the Vault URI, the Syslog viewer URI, and the current bootstrap Vault root token after a successful update.

Exact runbooks:

Constraints

  • The DevNet sandbox is not exercised automatically from this local scaffold.
  • Real Vault tokens and other non-sandbox secrets must stay out of git.
  • Cisco IOS XE and NX-OS bootstrap currently use network_cli over SSH for reliability during first-device setup.
  • The current NX-OS 9.3(5) sandbox image does not expose local-user password 6 syntax even with feature password encryption aes enabled. PassCycler enables the AES feature but uses the strongest local-user storage that the platform CLI actually supports.
  • The DevNet demo bootstrap also disables NX-OS password strength-check so the seeded break-glass password from .env.devbox can be applied deterministically during the sandbox baseline.
  • Per-device Vault aliases do not change the fact that a shared group password grants access to the whole group. Strong isolation requires per-device passwords, which remain out of scope for v1.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors