Skip to main content

Scan Azure Key Vaults for expiring secrets, certificates, and keys

Project description

certifyclouds

Do you know which Azure secrets expire this month?

Scan all your Azure Key Vaults across every subscription in 30 seconds. Free, open source, works in Azure Cloud Shell.

pip install certifyclouds                              # or: pipx install certifyclouds
cc-scan                                                # or: brew tap certifyclouds/certifyclouds && brew install certifyclouds

What you get

  • Cross-subscription inventory of every secret, certificate, and key
  • Expiry warnings: expired, <7 days, <30 days, <90 days (color-coded)
  • Security findings: public access, soft delete, RBAC, missing expiry dates
  • Export to JSON, CSV, or standalone HTML report
  • Works in Azure Cloud Shell with zero setup

Quick Start

# 1. Install (pick one)
pip install certifyclouds              # pip
pipx install certifyclouds             # pipx (isolated install)
brew tap certifyclouds/certifyclouds   # Homebrew (macOS/Linux)
brew install certifyclouds

# 2. Authenticate (skip in Azure Cloud Shell)
az login

# 3. Scan
cc-scan

On first run, you'll be prompted to register with your email (free, takes 10 seconds). Your API key is saved locally to ~/.certifyclouds/config.json.

Output

CertifyClouds Scanner v1.2.2
Authenticated as: you@company.com

Scanning Azure subscriptions...

Production (sub-abc123)
  vault-prod (eastus) - 45 secrets, 12 certificates, 3 keys
  vault-shared (westeurope) - 23 secrets, 5 certificates, 1 key

SUMMARY
  Subscriptions: 2    Vaults: 4    Total assets: 112
  Secrets: 88    Certificates: 20    Keys: 4

EXPIRY WARNINGS
  EXPIRED     3 secrets, 1 certificate
  < 7 days    2 secrets
  < 30 days   8 secrets, 2 certificates

SECURITY FINDINGS
  CRITICAL: 3    HIGH: 2    MEDIUM: 47    LOW: 1

  CRITICAL   Expired secret still enabled       vault-prod/db-password
  HIGH       Public network access enabled      vault-legacy
  MEDIUM     Secret has no expiry date          vault-prod/api-key

Usage

# Output formats
cc-scan --format table           # Default: pretty terminal output
cc-scan --format json            # Full JSON (pipe-friendly)
cc-scan --format csv             # Flat CSV (for spreadsheets)
cc-scan --format html            # Standalone HTML report

# Write to file
cc-scan --output report.html --format html
cc-scan --output scan.json --format json

# Filters
cc-scan --expiring 30            # Only items expiring within 30 days
cc-scan --expired                # Only already-expired items
cc-scan --type secrets           # Only secrets (or: certificates, keys)
cc-scan --vault vault-prod       # Specific vault(s) (repeatable)
cc-scan --subscription sub-123   # Specific subscription(s) (repeatable)

# Security summary only
cc-scan --security               # Show findings without per-item details

# Azure auth
cc-scan --auth cli               # Azure CLI credential (default)
cc-scan --auth default           # DefaultAzureCredential (managed identity/SP)

# Tuning
cc-scan --workers 10             # Parallel workers (default: 5, max: 20)
cc-scan --timeout 600            # Scan timeout in seconds (default: 300)

# Other
cc-scan --offline                # Skip license server validation
cc-scan --register               # Re-register / change email
cc-scan --key cc-scan-xxxxx      # Use a specific API key
cc-scan --version                # Show version
cc-scan --help                   # Show all options

Environment Variables

All flags can be set via environment variables (flags take priority):

CC_SCAN_KEY=cc-scan-xxxxx        # API key
CC_SCAN_AUTH=cli                 # Auth method
CC_SCAN_FORMAT=json              # Output format
CC_SCAN_WORKERS=10               # Workers
CC_SCAN_TIMEOUT=600              # Timeout
CC_SCAN_OFFLINE=true             # Offline mode

For service principal auth (used with --auth default):

AZURE_CLIENT_ID=...
AZURE_CLIENT_SECRET=...
AZURE_TENANT_ID=...

Exit Codes

Code Meaning
0 Scan completed, no critical/high findings
1 Scan completed, critical or high findings detected
2 Scan failed (auth error, network error, timeout)
3 Registration required (no key found or registration failed)

Non-zero exit codes make this CI/cron-friendly: cc-scan || notify-team.

Azure Permissions

Your identity needs these roles on each Key Vault:

Role Why
Key Vault Secrets User List and read secret properties
Key Vault Certificate User List and read certificate properties
Key Vault Crypto User List and read key properties
Reader List Key Vaults across subscriptions

Assign roles in Azure Portal: Key Vault > Access control (IAM) > Add role assignment.

If a vault has firewall restrictions, you'll see an inline error (the scan continues to the next vault).

Security Findings

The scanner checks for 11 security rules:

ID Severity What it checks
SEC-001 CRITICAL Expired secret still enabled
SEC-002 CRITICAL Expired certificate still enabled
SEC-003 HIGH Public network access enabled on vault
SEC-004 HIGH Soft delete disabled
SEC-005 HIGH Purge protection disabled
SEC-006 MEDIUM Secret has no expiry date set
SEC-007 MEDIUM Certificate has no expiry date set
SEC-008 MEDIUM RBAC authorization not enabled
SEC-009 LOW Standard SKU (no HSM backing)
SEC-010 INFO Secret expiring within 30 days
SEC-011 INFO Certificate expiring within 30 days

Privacy & Telemetry

CertifyClouds Scanner sends aggregate usage statistics to improve the product. Here's exactly what is sent:

Sent: API key, CLI version, counts (subscriptions, vaults, secrets, certificates, keys, expired, expiring soon, security findings, vaults with errors), scan duration.

Never sent: Vault names or URIs, secret/certificate/key names, secret values, subscription IDs or names, Azure tenant IDs, resource group names, tags, certificate subjects or thumbprints.

Use --offline to skip license server validation calls (key telemetry and version checks). Azure SDK calls are unaffected — the scanner still requires Azure connectivity to read Key Vault data.

Source code is open and auditable: codeberg.org/hus/cc/scanner

Troubleshooting

"No Azure credentials found" Run az login to authenticate, or set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID for service principal auth.

Vault shows "Firewall restriction" Run cc-scan from an allowed network or add your IP in Azure Portal (Key Vault > Networking).

Vault shows "Access denied" Your identity needs the roles listed in Azure Permissions.

"Could not reach license.certifyclouds.com" Check internet connection. Behind a proxy? Set HTTPS_PROXY. Or use --offline mode.

Slow scans Increase workers: cc-scan --workers 10. Each subscription is scanned in parallel.

Requirements

  • Python 3.9+
  • Azure CLI (az login) or service principal credentials
  • Network access to Azure management and Key Vault data plane APIs

License

Apache 2.0. See LICENSE.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

certifyclouds-1.2.2.tar.gz (28.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

certifyclouds-1.2.2-py3-none-any.whl (34.7 kB view details)

Uploaded Python 3

File details

Details for the file certifyclouds-1.2.2.tar.gz.

File metadata

  • Download URL: certifyclouds-1.2.2.tar.gz
  • Upload date:
  • Size: 28.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for certifyclouds-1.2.2.tar.gz
Algorithm Hash digest
SHA256 b765b51ee07b23e37e8fb9bd470fb763ce69f33bc9118904ecf228bb592e921f
MD5 e928d46a2fe890731812b2f417db161b
BLAKE2b-256 ac6b4460616d24a950eb290728aff7f25e8e2f9ed9749f23a2a57def0c6dfccb

See more details on using hashes here.

File details

Details for the file certifyclouds-1.2.2-py3-none-any.whl.

File metadata

  • Download URL: certifyclouds-1.2.2-py3-none-any.whl
  • Upload date:
  • Size: 34.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for certifyclouds-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9ed30db2f059f00da36ae1ef47b0c9815c01f1a4ffc6052243da669977c4b863
MD5 664b3a16a18a429d1b3234abfb4162f7
BLAKE2b-256 4da7431262664cfc2473a04bdbdb44f5aadd8cc9a9d4719d1768567c8c84d159

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page