Skip to main content

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

Project description

cc-scanner

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 cc-scanner
cc-scan

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
pip install cc-scanner

# 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.0
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 / invalid API key

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 disable all network calls to the license server. The scan works fully offline.

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.0.tar.gz (28.5 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.0-py3-none-any.whl (34.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for certifyclouds-1.2.0.tar.gz
Algorithm Hash digest
SHA256 a91a8db181252e52ec3aabeec925622fe17d5463d472b73b4008fe623e6d675c
MD5 28313e923396b617f6c9a26450b41082
BLAKE2b-256 0f56fadadb4b685146b0155130c1b5e0dbde76c09e8b2c192b6dee0d67b3b049

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for certifyclouds-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 526ab9d9d170f14d94a3a8a09f93642bee5f921b7685db79268f632735e44c25
MD5 875119b7e42e0829254833224e40401c
BLAKE2b-256 cb531597dbd03caa1ba704969a55f85826a230fc090ec1fe2471ea41b5a7213e

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