ConfigStash Agent
A small on-premise collector that backs up your network device configs (MikroTik RouterOS, Ubiquiti EdgeRouter/EdgeSwitch/UniFi Switch) to your ConfigStash server.
Your device credentials never leave your network. The agent connects to devices over SSH locally and pushes only the resulting config text to the API over outbound HTTPS, authenticated with an agent token. No inbound ports needed.
Quick Start: from zero to first backup in 5 minutes
Prerequisites: Python 3.12+, a ConfigStash account, SSH access to at least one device.
1. Install (30 sec)
pip install configstash-agent
2. Get an agent token (1 min)
In the ConfigStash web UI: Settings → Agents → Create agent.
Copy the token (cst_agent_...) — it is shown only once.
3. Initialize (30 sec)
configstash-agent init
Enter your API URL (e.g. https://api.yourdomain.com) and the agent token.
This creates ~/.configstash/config.yaml (permissions 600).
4. Add a device (1 min)
In the web UI: Dashboard → Add device. Copy the device ID it shows, then
add the device to ~/.configstash/config.yaml:
devices:
- name: "Office MikroTik"
device_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # from the web UI
host: 192.168.88.1
device_type: mikrotik_routeros # mikrotik_routeros | ubiquiti_edgerouter | ubiquiti_edgeswitch | ubiquiti_unifiswitch
username: admin
password: "your-ssh-password"
port: 22
Tip: create a dedicated read-only SSH user on the device for backups.
5. Test and run (2 min)
configstash-agent test # dry run: SSH connect + collect, nothing sent
configstash-agent run # collect and upload your first backup
Open the web UI — your backup is there. Done. 🎉
6. Keep it running
configstash-agent install-service # auto-start on boot (systemd / launchd)
By default backups run every 6 hours (schedule: "0 */6 * * *" — standard
cron syntax, edit in config.yaml) with a heartbeat every 5 minutes.
No devices yet? Try demo mode
configstash-agent demo --api-url https://api.yourdomain.com --token cst_agent_... --repeat 3
Creates a virtual MikroTik and uploads realistic configs with changes between runs — great for seeing the diff viewer in action.
All commands
| Command | What it does |
|---|---|
init |
Interactive config creation |
test |
Dry run: SSH to all devices, don't upload |
run |
One-shot: collect and upload all devices |
start |
Foreground daemon on cron schedule (-d to background) |
stop / status |
Manage the running daemon |
install-service / uninstall-service |
systemd/launchd auto-start |
demo |
Fake device backups, no SSH needed |
uninstall |
Remove agent and local data (cloud backups stay) |
Docker
cp config.example.yaml config.yaml # edit it
docker compose up -d
On Linux, uncomment network_mode: host in docker-compose.yml if your
devices aren't reachable from the container network.
What gets uploaded (and what never does)
Device credentials never leave this machine — they live only in
~/.configstash/config.yaml and are used for outbound SSH to your devices.
The only thing sent to the API is config text, and by default it is
sanitized first:
- Secrets are masked. Passwords, pre-shared keys, SNMP communities and
similar values are replaced with
**REDACTED**before upload. RouterOS/exportalready omits sensitive fields; EdgeOS / EdgeSwitch output prints them in clear text, so this matters. - Public IPs are pseudonymized. Globally routable addresses become stable
EXT-IP-xxxxxxtokens derived from a salt stored only on this machine (~/.configstash/ip_salt). The same address always maps to the same token, so diffs stay meaningful — but your public addresses are never stored in the cloud. Private ranges (10.x,192.168.x, …) are kept as-is.
Both passes can be disabled in config.yaml (sanitize_secrets,
sanitize_public_ips) if you prefer verbatim backups — see
config.example.yaml for the trade-off.
Notes
- Failed uploads are queued in
~/.configstash/pending/and retried on the next run — safe across API downtime. - All local state lives in
~/.configstash/(mode700). - Always use an
https://API URL in production — the agent warns otherwise.
License
Metadata
Release files for configstash-agent 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| configstash_agent-0.2.0.tar.gz | 21.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| configstash_agent-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.4 kB
Release files / configstash_agent-0.2.0.tar.gz
| Download URL | configstash_agent-0.2.0.tar.gz |
|---|---|
| Size | 21.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4bd546bb9c5897ba1c7dd3b691dfed47055efb5c4954975c3281e918a950d5ee
|
|
BLAKE2b-256 checksum How to use checksums |
6f7f8b446a81d058254959a547624f52004c887576e2ab18cb61e8bda6263fb3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / configstash_agent-0.2.0-py3-none-any.whl
| Download URL | configstash_agent-0.2.0-py3-none-any.whl |
|---|---|
| Size | 22.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
79c01bf1259101b32dbf819a4d394d56b9b0b3cc83fad067a3802b1d72ede81b
|
|
BLAKE2b-256 checksum How to use checksums |
db482cc0961eafbbbcd08098c6321b0fb167f1bfaf5793bcfaabe609c2e40c60
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Security for configstash-agent 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.