AXGhost runs with privileged access to a production server. Security is not an afterthought — it is the product's premise. This document covers the threat model, the defense layers, and how to report vulnerabilities.
Do not open public GitHub issues for security bugs.
- Email:
security@aevonx.app - Encrypted submission: use the PGP key published on the AevonX website (
https://aevonx.app/.well-known/pgp-key.asc). - Include: affected version, steps to reproduce, impact assessment, and any proof-of-concept.
We commit to:
- Acknowledging receipt within 72 hours.
- Providing an initial assessment within 7 days.
- Coordinating disclosure timing with the reporter.
- Publicly crediting the reporter in release notes unless anonymity is requested.
Please allow us at least 90 days to ship a fix before public disclosure.
Only the latest stable minor version receives security updates. Older versions should be upgraded.
| Version | Supported |
|---|---|
| latest | Yes |
| older | No |
AXGhost is designed against the following adversaries:
| Adversary | Capability | Mitigation |
|---|---|---|
| Unauthorized Telegram user | Knows the bot username, spams messages | Silent drop for non-whitelisted IDs; no response, no error, no enumeration path |
| Authorized user with a compromised Telegram account | Can issue arbitrary commands | Forbidden command list; destructive confirmations; rate limiting; full audit trail |
| Network attacker (MITM) | Intercepts traffic between server and Telegram | All traffic is TLS to api.telegram.org; no alternative egress |
| Local non-root user on the server | Reads config, logs, or sockets | Config 0600, owned by aevonx-axghost; logs group-readable but not world-readable; stats API bound to localhost |
| Supply-chain / backdoored dependency | Introduces malicious code via Go modules | Minimal third-party dependencies; pinned via go.sum; built with CGO_ENABLED=0 for reproducibility |
| Cloud AI provider | Reads command stream | Not applicable — AXGhost has no AI component. No inference, no third-party API beyond Telegram |
Out of scope:
- Physical access to the server hardware.
- Root-level compromise of the host OS (AXGhost cannot defend against an attacker who already owns the kernel).
- Telegram infrastructure compromise (trust boundary assumed at
api.telegram.org).
Mandatory user-ID whitelist. Only Telegram user IDs listed in authorized_user_ids receive any processing. Unauthorized messages are dropped silently — no error, no acknowledgement, no response — to eliminate enumeration.
- Empty whitelist = reject all. There is no fallback, no first-come-first-served.
- IDs are revoked at runtime with
axghost exec auth.revoke <id>. - Config reload (
SIGHUPoraxghost exec config.reload) applies changes without restart.
Every supported operation is classified into one of four safety levels:
| Level | Examples | Confirmation |
|---|---|---|
| ReadOnly | status, list, info, show, report |
Never |
| Reversible | start, stop, restart, reload, install |
Configurable |
| Destructive | delete, kill, remove, drop, purge |
Always required |
| Forbidden | rm -rf /, shutdown, mkfs, fork bombs |
Never executed |
Forbidden patterns are hard-coded regex and cannot be overridden by configuration:
rm -rf /and variantsrm -rf /*mkfs.*(filesystem format)dd if=... of=/dev/[sh]d*(raw disk writes):(){ :|:& };:(fork bomb)shutdown,reboot,init 0chmod -R 777 /,chown -R ... /- Writes to
/dev/[sh]d* - Access to
/etc/shadow passwd root
Every parameter extracted from natural language is validated before any shell interpolation:
- Service names must match
^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$. - Ports must be integers in
[1, 65535]. - Domains must match a strict DNS label regex.
- Database names must be valid SQL identifiers and are checked against a reserved-name list (
information_schema,mysql,postgres,template0,template1, etc.). - File paths are restricted to whitelisted directories per handler; no traversal via
...
String interpolation with unvalidated input is a build-breaking lint rule across internal/executor/.
cmd.Env = []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"HOME=/root",
"LANG=C.UTF-8",
"LC_ALL=C.UTF-8",
}- Minimal environment — no inherited variables from the daemon process.
- Timeout per command (30s default, configurable).
- Runs as
aevonx-axghostwith scoped sudo — only the subset of commands defined in/etc/sudoers.d/aevonx-axghostis permitted. shell.Quote()wraps every dynamic argument before it reachesbash -c.
Per-chat sliding windows enforce:
- 30 commands per minute — generic flood protection.
- 5 destructive commands per hour — slows accidental or malicious bulk deletion.
- 30-second cooldown after 3 consecutive failures — defeats brute-force parameter guessing.
Every command execution writes a JSONL record to /var/log/aevonx/plugins/axghost/audit.log:
{
"timestamp": "2026-04-14T10:22:11Z",
"chat_id": 123456789,
"username": "ops-admin",
"input": "restart nginx",
"intent": "ServiceRestart",
"command": "systemctl restart nginx",
"exit_code": 0,
"duration_ms": 412,
"safety": "reversible",
"result": "success"
}- Rotated daily or at 50 MB.
- Retained for 30 days by default (configurable).
- Written synchronously before the response is returned to the user — a failed log write aborts execution.
- Telegram bot token lives only in
config.avx(mode 0600, owned byaevonx-axghost). - Masked in every log line:
123...XYZ9. - Never echoed in Telegram messages or API responses.
- Cleared from memory once the HTTP client is constructed.
- Server credentials (database passwords, SSH keys, etc.) are never stored, read, or cached by AXGhost. Database-user creation generates a one-shot password, shown once in the reply, and not persisted.
| Mode | Inbound | Outbound |
|---|---|---|
| Polling (default) | None | HTTPS to api.telegram.org |
| Webhook | TLS 8443 on /webhook/<32-char-random> |
HTTPS to api.telegram.org |
- Webhook URLs include a 32-character random secret path component.
- TLS is mandatory in webhook mode (self-signed accepted by Telegram).
- The local stats API (
127.0.0.1:<random-port>) never binds to a public interface and returns no sensitive data (no tokens, no message text).
- Go 1.22+,
CGO_ENABLED=0— single static binary, reproducible. - Dependencies pinned via
go.sum. - Release artifacts published on GitHub with SHA-256 checksums and detached signatures.
setup.shverifies the checksum before installing.
| Data | Stored locally | Sent to Telegram | Sent elsewhere |
|---|---|---|---|
| Bot token | config.avx (0600) | API auth header | Never |
| User messages | Audit log (30 days) | Never re-sent | Never |
| Command output | Audit log (truncated) | Reply to user | Never |
| Server state | Never persisted beyond audit | Summaries only | Never |
| Host credentials | Never accessed | Never | Never |
| Session context | SQLite (local, 0600) | Never | Never |
AXGhost does not:
- Talk to any third party other than
api.telegram.org. - Read or store OS credentials, private keys, or secrets.
- Access files outside the command scope of its handlers.
- Run commands directly as root (always via scoped sudo).
- Retain message content beyond the audit retention window.
If you run AXGhost in production:
- Create a dedicated Telegram bot — do not reuse a bot you use for anything else.
- Populate
authorized_user_idswith exactly the IDs that need access. Remove staff IDs when people leave. - Prefer polling mode unless you have a reason for webhooks — it eliminates the inbound attack surface.
- If you use webhooks, restrict port 8443 in your firewall to Telegram's published IP ranges.
- Ship audit logs to a central log system (rsyslog, Loki, Elastic) so they survive server compromise.
- Keep
execution_timeout_seclow (default 30s is usually enough; some installs reduce it to 10s). - Monitor the
deniedandforbiddenresult counters on the stats API — non-zero values mean somebody is trying something they shouldn't. - Upgrade promptly when new releases ship security fixes.
- Telegram metadata visibility. Telegram sees who messages the bot, when, and from which chat. Only the payload content is subject to AXGhost's privacy guarantees; metadata is always visible to Telegram.
- Compromised authorized account. If an attacker steals a whitelisted Telegram session, they can issue any non-forbidden command subject to rate limiting. Mitigate with Telegram 2FA, device pruning, and strict whitelist hygiene.
- Man-in-the-middle on webhook. A compromised DNS or CA can MITM the webhook endpoint if you use self-signed certs without pinning. Prefer a real Let's Encrypt certificate in webhook mode.
- Command-output truncation. Audit logs truncate very large outputs to 64 KiB per entry. If full output is required for forensics, raise
audit_max_output_bytesand rotate more aggressively.
- Email:
security@aevonx.app - PGP:
https://aevonx.app/.well-known/pgp-key.asc - Response SLA: 72 hours acknowledgement, 7 days assessment, 90-day embargo.