Azure Container Instance Distributed Operations
Project description
acido 🔥
The open-source engine powering Secrets by Merabytes™
Disrupting how secrets, tokens, and one-time credentials are shared — forever.
acido isn’t just another CLI tool. It’s the backbone of an infrastructure-first rethink of how secrets, tokens and one-time credentials are built, deployed and consumed.
Already powering Secrets by Merabytes™ — the first truly open-source secret-sharing app — acido installs like a developer tool and scales like an enterprise service.
Deploy fleets of workloads on Azure Container Instances in minutes.
Leverage full transparency: open source, auditable, no lock-in.
Built for the next generation of identity, secrets and “one-time everything”.
Whether you’re building a secure secret-sharing system, a distributor of short-lived credentials, or simply pushing containerised tasks to the edge — acido gives you the power, the scale and the freedom of open source.
Table of Contents
- Why Acido?
- Installation
- Quick Start
- CLI Reference
- Examples
- Docker Usage
- AWS Lambda Support
- GitHub Self-Hosted Runners
- Secrets Sharing Service
- Credits
Why Acido?
Speed: Distribute scans across 10, 50, or 100+ containers. What takes 24 hours on one machine completes in minutes with parallelization.
Cost-Effective: Pay only when scanning. Spin up 100 containers for 30 minutes, then destroy them - no idle infrastructure costs.
Tool Support: Works with any containerized security tool (nmap, masscan, Nuclei, Nikto, gowitness, etc.).
Simple: Split targets automatically, deploy containers, collect results, cleanup - all automated.
+---------------------------+
| 1. Prepare targets file |
| urls.txt |
+------------+--------------+
|
v
+---------------------------+
| 2. Configure (first time) |
| acido configure |
+------------+--------------+
|
v
+-----------------------------+
| 3. Create nuclei image |
| `acido create nuclei |
| --image projectdiscovery/|
| nuclei:latest` |
+------------+----------------+
|
v
+----------------------------------------------+
| 4. Run distributed scan fleet |
| ` acido fleet nuclei-scan |
| -n 10 |
| -im nuclei |
| -t "nuclei -list input" |
| -i urls.txt |
| -o results |
| --rm-when-done (optional auto cleanup)` |
+------------+---------------------------------+
|
v
+---------------------------+
| 5. View results |
| Open 'results' file |
+------------+--------------+
|
v
+------------------------+
| 6. Cleanup acido fleet |-- Yes (auto --rm-when-done)
+------------------------+
|
No v
+---------------------------+
| Manual cleanup |
| `acido rm nuclei-scan` |
+---------------------------+
(If --rm-when-done was used, skip manual cleanup.)
Inspired by axiom.
Installation
Prerequisites:
- Python 3.7+
- Azure account (free tier works)
Quick Setup in Azure Cloud Shell
-
Open Azure Cloud Shell:
- Go to Azure Portal and click the Cloud Shell icon (>_)
-
Run the install script:
curl -o install.sh https://raw.githubusercontent.com/merabytes/acido/main/install.sh chmod +x install.sh # Replace SUB_ID with your Azure Subscription ID ./install.sh \ -s SUB_ID \ -g acido-rg \ -l eastus \ -p acido \ -a acidocr \ -S acidostore123 \ --show-secret \ --emit-env-file acido.env \ --create-rg
This creates: Service Principal, ACR, Storage Account, blob container, and generates a complete environment file.
-
Load environment and install:
source acido.env pip install acido
-
You're ready! All Azure credentials are configured via environment variables.
Quick Start
- Create scanning image from GitHub:
acido create https://github.com/projectdiscovery/nuclei
- Run distributed scan:
echo -e "example.com\ntest.com" > targets.txt
acido fleet nuclei-scan -n 3 -im nuclei -t 'nuclei -list input' -i targets.txt
- Manage containers:
acido ls # List all instances
acido rm nuclei-scan # Remove specific fleet
- Manage IP addresses:
acido ip create pentest-ip # Create IPv4 address
acido ip ls # List all IPs
acido ip rm pentest-ip # Remove IP address
CLI Reference
Core Commands
# Create images
acido create https://github.com/projectdiscovery/nuclei
acido create nmap --image nmap:latest
# Deploy fleet
acido fleet <name> -n <count> -im <image> -t '<command>' -i <input-file>
# Manage containers
acido ls # List all instances
acido rm <name> # Remove instances
# Manage IP addresses
acido ip create <name> # Create IPv4 address
acido ip ls # List all IPs
acido ip rm <name> # Remove IP
acido ip select # Select IP interactively
Examples
Distributed Scanning
# Nuclei scan across 10 containers
acido fleet nuclei-scan -n 10 -im nuclei -t 'nuclei -list input' -i urls.txt
# Nmap scan with auto-cleanup
acido fleet nmap-scan -n 5 -im nmap -t 'nmap -iL input -p-' -i targets.txt --rm-when-done
Container Management
# List all running instances
acido ls
# Remove specific fleet
acido rm nuclei-scan
# Remove all matching pattern
acido rm 'scan-*'
IP Address Routing
# Create standalone public IP (no NAT Gateway stack)
acido ip create my-ip
# Create public IP with full NAT Gateway stack for egress
acido ip create nat-ip --with-nat-stack
# Select IP for use with containers
acido ip select
# Deploy with IP routing (containers use selected IP for egress)
acido fleet scan -n 10 -im nmap -t 'nmap -iL input' -i targets.txt
# List all IPs (shows NAT stack indicator)
acido ip ls
# Clean IP configuration from local config
acido ip clean
# Cleanup
acido ip rm my-ip
Port Forwarding (Bidirectional Connectivity)
Acido supports bidirectional connectivity for containers that need to accept inbound connections (e.g., VoIP servers, game servers, SSH bastions).
Key Concepts:
- Default behavior: Containers use NAT Gateway for egress-only (no changes to existing workflows)
- Bidirectional mode: Use
--bidirectionalflag withacido runto enable inbound connectivity - Public IP assignment: Bidirectional containers get a dedicated public IP for inbound traffic
- Fleet unchanged:
acido fleetalways uses NAT Gateway (no bidirectional support)
💼 Enterprise Option: For advanced security and centralized control, see Azure Firewall Integration (Solution 4 - ~$900/month)
🔥 NEW: Automatic Firewall Rules: Use --expose-ip with --bidirectional to automatically create Azure Firewall rules, route tables, and network rules. See EXPOSE_IP_FEATURE.md for details.
Examples:
# 1. Create a standalone public IP (no NAT Gateway needed for bidirectional)
acido ip create voip-ip
acido ip select
# 2. Deploy VoIP server with bidirectional connectivity
acido run voip-server \
-im asterisk:latest \
-t "./start-asterisk.sh" \
--bidirectional \
--expose-port 5060:udp \
--expose-port 5060:tcp \
--cpu 4 \
--ram 8 \
-d 86400
# 3. Deploy game server (Minecraft)
acido run minecraft \
-im minecraft-server:latest \
-t "./start.sh" \
--bidirectional \
--expose-port 25565:tcp \
--cpu 2 \
--ram 4 \
--no-cleanup
# 4. Deploy SSH bastion (time-limited for security)
acido run ssh-bastion \
-im ubuntu:20.04 \
-t "service ssh start && sleep infinity" \
--bidirectional \
--expose-port 22:tcp \
-d 3600 # Auto-cleanup after 1 hour
# 5. Deploy with automatic firewall rules (requires configured firewall)
# Restrict access to specific source IPs
acido run api-server \
-im nginx:latest \
--bidirectional \
--expose-ip 192.168.1.100 \
--expose-ip 192.168.1.101 \
--expose-port 80:tcp \
--expose-port 443:tcp \
-d 7200
# 6. DMZ mode - allow all traffic on all ports
acido run dmz-server \
-im myserver \
--bidirectional \
--dmz \
-d 86400
# 7. Custom resource allocation for fleet (no bidirectional support)
acido fleet scan -n 10 -im nmap \
-t 'nmap -iL input' -i targets.txt \
--cpu 8 --ram 16
Important Notes:
- The
--bidirectionalflag is only available foracido run(single containers) acido fleetdoes NOT support--bidirectional(fleet always uses NAT Gateway for egress)- The
--expose-portformat isPORT:PROTOCOLorPORT_START-PORT_END:PROTOCOL(e.g.,5060:udp,8080:tcp,10000-10099:udpfor ranges) - Port ranges are expanded automatically (max 100 ports per range)
- Multiple ports can be exposed by repeating
--expose-port - NEW:
--expose-ip <source-ip>flag with--bidirectionalenables automatic Azure Firewall rule creation with source IP filtering- Specifies source IP addresses allowed to access container through firewall
- Can be specified multiple times for multiple source IPs
- NAT rules use firewall's public IP as destination, translate to container at 10.0.2.4
- See EXPOSE_IP_FEATURE.md for complete documentation
- NEW:
--dmzflag allows all traffic on all ports to container (requires firewall)- Mutually exclusive with --expose-ip
- Creates single NAT rule for unrestricted access
- Container IP is printed after deployment for easy access
- Use
--cpuand--ramto configure container resources (works for both run and fleet)- Default for
acido run: 4 CPU cores, 16 GB RAM (when not specified) - Default for
acido fleet: 8 CPU cores, 8 GB RAM (when not specified) - reduced to fit within Azure quota limits
- Default for
- For
acido run:--entrypointand--taskare both optional - if not provided, uses the default entrypoint/cmd from the Docker image - For
acido fleet:--taskis required to specify the command to execute across the fleet
Command Execution:
--task/-t: Override the container's CMD (command to execute)- Optional for
acido run(uses image default if not provided) - Required for
acido fleet
- Optional for
--entrypoint: Override the container's ENTRYPOINT (optional foracido run)- Both can be used together: entrypoint is executed with task as arguments
Environment Variables
Both acido run and acido fleet support setting custom environment variables using the -e or --env flag, similar to Docker.
Two formats supported:
KEY=value- Set KEY to the specified valueKEY- Use value from your current environment
Examples:
# Set environment variables with explicit values
acido run myapp \
-im myapp:latest \
-e DEBUG=true \
-e LOG_LEVEL=info \
-e API_KEY=secret123
# Use environment variables from your shell
export DATABASE_URL="postgresql://localhost/mydb"
export API_TOKEN="xyz789"
acido run myapp \
-im myapp:latest \
-e DATABASE_URL \
-e API_TOKEN \
-e APP_ENV=production
# Works with fleet too
acido fleet workers -n 5 \
-im worker:latest \
-t "python worker.py" \
-e WORKER_POOL=large \
-e REDIS_URL \
-e DEBUG=false
Notes:
- Multiple
-eflags can be specified - Custom env vars are merged with acido's built-in environment variables
- If a KEY is not found in your environment, a warning is shown and it's skipped
Docker Usage
Acido can be run in a Docker container for isolated and reproducible environments.
Quick Start:
Build the Docker image from the latest version:
./build.sh
Or from a specific branch/tag:
./build.sh v0.45.0
./build.sh feature-branch
Run acido commands:
# Show help
docker run --rm acido-cli:main --help
# Run with Azure credentials
docker run --rm \
-e AZURE_RESOURCE_GROUP=your-rg \
-e IMAGE_REGISTRY_SERVER=your-registry.azurecr.io \
-e IMAGE_REGISTRY_USERNAME=your-username \
-e IMAGE_REGISTRY_PASSWORD=your-password \
-e STORAGE_ACCOUNT_NAME=your-storage \
acido-cli:main ls
Key Features:
- Pre-built Docker image with acido CLI
- Isolated environment for testing
- Easy distribution and deployment
- Automated build script (
build.sh) - CI/CD tested in GitHub Actions
Documentation:
- See DOCKER.md for complete Docker usage guide
- Includes examples for mounting files and environment variables
AWS Lambda Support
Acido can be deployed as an AWS Lambda function, enabling serverless security scanning workflows.
Key Features:
- Serverless invocation via AWS Lambda
- Automatic container provisioning in Azure
- JSON-based event interface
- Continuous deployment via GitHub Actions
- New: Full CRUD operations support (fleet, run, ls, rm, ip)
Supported Operations:
- Fleet Operation - Distributed scanning across multiple containers:
{
"operation": "fleet",
"image": "nmap",
"targets": ["merabytes.com", "uber.com"],
"task": "nmap -iL input -p 0-1000"
}
- Run Operation - Single ephemeral instance:
{
"operation": "run",
"name": "runner-01",
"image": "ubuntu",
"task": "./run.sh"
}
- List Operation - List all container instances:
{
"operation": "ls"
}
- Remove Operation - Remove container instances:
{
"operation": "rm",
"name": "fleet-1"
}
- IP Management Operations - Manage IPv4 addresses:
{
"operation": "ip_create",
"name": "pentest-ip"
}
{
"operation": "ip_ls"
}
{
"operation": "ip_rm",
"name": "pentest-ip"
}
Quick Example:
{
"image": "nmap",
"targets": ["merabytes.com", "uber.com", "facebook.com"],
"task": "nmap -iL input -p 0-1000"
}
Documentation:
- See LAMBDA.md for complete deployment and usage instructions
- See LAMBDA_API_EXAMPLES.md for detailed API usage examples and CLI equivalents
- Example payload: examples/example_lambda_payload.json
- Automatic deployment workflow: .github/workflows/deploy-lambda.yml
REST API Client (acido-client)
A separate lightweight Python package is available for interacting with acido Lambda functions via REST API:
pip install acido-client
Key Features:
- Lightweight (minimal dependencies)
- Completely independent from main acido package
- Supports all 7 Lambda operations
- Python API and CLI interface
Quick Example:
from acido_client import AcidoClient
client = AcidoClient() # Uses LAMBDA_FUNCTION_URL from environment
# Fleet operation
response = client.fleet(
image="kali-rolling",
targets=["merabytes.com", "uber.com"],
task="nmap -iL input -p 0-1000"
)
# List instances
response = client.ls()
CLI Usage:
export LAMBDA_FUNCTION_URL="https://your-lambda-url.lambda-url.region.on.aws/"
acido-client fleet --image kali-rolling --targets example.com --task "nmap -iL input -p 0-1000"
acido-client ls
See acido-client/README.md for complete documentation.
GitHub Self-Hosted Runners
Acido supports spinning up ephemeral GitHub self-hosted runner containers on Azure Container Instances.
Key Features:
- Single ephemeral container instances with auto-cleanup
- Configurable duration (up to 15 minutes for Lambda compatibility)
- Ideal for on-demand CI/CD workers
- Cost-effective: pay only for runtime
- AWS Lambda orchestration support
Quick Example:
Run a GitHub runner for 15 minutes via CLI:
acido run github-runner-01 \
-im github-runner \
-t './run.sh --url https://github.com/myorg/myrepo --token TOKEN' \
-d 900
Or via AWS Lambda:
{
"operation": "run",
"name": "github-runner-01",
"image": "github-runner",
"task": "./run.sh --url https://github.com/myorg/myrepo --token ${RUNNER_TOKEN}",
"duration": 900
}
Documentation:
- See GITHUB_RUNNERS.md for complete setup and usage instructions
- Example payload: examples/example_lambda_github_runner_payload.json
Secrets Sharing Service
Acido includes a OneTimeSecret-like service for secure secrets sharing via AWS Lambda and Azure KeyVault.
Key Features:
- Generate UUID-based secrets
- One-time access (auto-delete after retrieval)
- Secure storage in Azure KeyVault
- Serverless AWS Lambda deployment
- Optional CloudFlare Turnstile bot protection
Quick Example:
Create a secret:
{
"action": "create",
"secret": "Your secret message here"
}
Retrieve the secret (one-time only):
{
"action": "retrieve",
"uuid": "generated-uuid-from-create"
}
Documentation:
- See SECRETS.md for complete documentation
- Example payloads: examples/example_lambda_secrets_create_payload.json and examples/example_lambda_secrets_retrieve_payload.json
- Automatic deployment workflow: .github/workflows/deploy-lambda-secrets.yml
Credits
- Xavier Álvarez (xalvarez@merabytes.com)
- Juan Ramón Higueras Pica (jrhigueras@dabbleam.com)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acido-0.53.0.tar.gz.
File metadata
- Download URL: acido-0.53.0.tar.gz
- Upload date:
- Size: 78.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db014b84f575c82ee4e60d233c4ac81d447d2e1e66fbb9f7ae4cd1a3c0080cd8
|
|
| MD5 |
75cac3dba5ae24fa0265b4cf8c956141
|
|
| BLAKE2b-256 |
a19db6a5d608991e561c831582dbb5792533d9ce83f4633c7b9d8f51c289039a
|
File details
Details for the file acido-0.53.0-py3-none-any.whl.
File metadata
- Download URL: acido-0.53.0-py3-none-any.whl
- Upload date:
- Size: 65.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8052b4e07bcce6c1037689f15399b0ff8e7f9cdcee238264c9c7f1a34e4ed963
|
|
| MD5 |
8950f7df4fa93bdb464fb6f2f2aa640e
|
|
| BLAKE2b-256 |
b9c231d5617e7cc88d154f1ad8e78b2499eb50071442c4e7228a8abe6cb08729
|