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.
- Why Acido?
- Installation
- Quick Start
- CLI Reference
- Examples
- Docker Usage
- AWS Lambda Support
- GitHub Self-Hosted Runners
- Secrets Sharing Service
- Credits
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.
Prerequisites:
- Python 3.7+
- Azure account (free tier works)
-
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-rgThis 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.
- 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# 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# 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# List all running instances
acido ls
# Remove specific fleet
acido rm nuclei-scan
# Remove all matching pattern
acido rm 'scan-*'# 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-ipAcido 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)
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. 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 16Important 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 - 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
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=falseNotes:
- 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
Acido can be run in a Docker container for isolated and reproducible environments.
Quick Start:
Build the Docker image from the latest version:
./build.shOr from a specific branch/tag:
./build.sh v0.45.0
./build.sh feature-branchRun 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 lsKey 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
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
A separate lightweight Python package is available for interacting with acido Lambda functions via REST API:
pip install acido-clientKey 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 lsSee acido-client/README.md for complete documentation.
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 900Or 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
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
- Xavier Ćlvarez (xalvarez@merabytes.com)
- Juan Ramón Higueras Pica (jrhigueras@dabbleam.com)