Browser authentication
How the integrate skill gets an API key without your copying one, the local callback listener, its two backends, and the three fallbacks when it cannot run.
The axonpush-integrate skill needs an API key and a tenant ID. Rather than
asking you to find them in the dashboard and paste them into a terminal, it
runs a small login helper that gets them out of a browser session you are
probably already signed into.
The helper is skills/axonpush-integrate/helpers/login.sh in
axonpush/skills. Every supported agent
runs the same script.
The flow
- The helper picks a free port
Non127.0.0.1and starts a listener there. - It opens
https://app.axonpush.xyz/wizard-auth?port=Nin your browser. - You sign in, or you already are, pick an organisation, then click Generate API Key and Send to Wizard.
- The page redirects to
http://127.0.0.1:N/callback?api_key=…&tenant_id=…. - The listener reads both values, prints
{"api_key": "…", "tenant_id": "…"}to stdout, and shuts down. - The skill parses that and calls
helpers/env.sh, which writes the credentials to.env.localif that file already exists, and to.envotherwise.
The callback path is /callback. A request to any other path gets a
Waiting for authentication… holding page, and a /callback missing either
field gets a 400. The listener only exits once it has both.
Everything is subject to a 120-second timeout. Exit codes are 0 for
success, 1 for a timeout or missing fields, and 2 when no listener tool is
available.
Listener backends
The helper needs one of two things on your PATH:
python3, preferred. Ahttp.server.BaseHTTPRequestHandlerbound to127.0.0.1.nc, fallback, invoked asnc -l -p $PORT -q 1.
If neither exists it exits 2 immediately without opening a browser. That is
the most common failure on a minimal container image, and it is not a network
problem, install one of the two, or use the manual fallback below.
To open the browser it tries xdg-open, then open, then start. When none of
them work it prints the URL for you to open by hand, which is what makes this
workable over SSH with local port forwarding.
When the browser flow will not work
Three ways round it, and the skill offers them in this order.
Credentials already in the environment
If AXONPUSH_API_KEY and AXONPUSH_TENANT_ID are already set, the skill skips
login entirely. In CI, or on a machine you have already configured, this is the
path you want.
MCP
If an axonpush MCP server exposing provision_app is connected to your agent,
the skill uses it instead of the browser. It calls
provision_app({ appName, channelNames, environment? }) and receives a one-time
ingest key. The MCP token needs the mcp:setup scope.
The key this returns is publish-only, which is why the skill verifies the
integration through the MCP server’s search_events rather than through the
REST list endpoint, a publish-only key cannot read events back.
Paste a key
Choose Enter API key manually and paste one from the
dashboard. The skill writes the
same file and continues from step 6. AXONPUSH_TENANT_ID defaults to 1 if you
do not supply one, which is only right on a single-tenant deployment, check it.
Self-host
Set AXONPUSH_BASE_URL to your own deployment before running the skill. The
login helper also takes the app URL as its first positional argument, so
bash login.sh https://app.axonpush.internal points the browser flow at a
self-hosted dashboard.
What the key is used for
The skill talks to the REST API with two headers:
X-API-Key: <key>
x-tenant-id: <tenant>
It uses them to create an app and channels, publish a test event, and read that event back. Nothing else.
The key the dashboard generates for the wizard is named wizard-generated and
carries a broad set of scopes: publish, events:read, traces:read,
analytics:read, alerts:manage, apps:manage, channels:manage and
webhooks:manage. That is a broad key for an application to hold in production,
treat it as a development credential and mint a narrower, environment-pinned one
for deploys. See
Environments.
Security notes
- The listener binds to
127.0.0.1only, never to a network interface. - It serves exactly one path that matters and exits as soon as it has both credentials, but it is a real HTTP listener while it waits, and it waits up to 120 seconds. It is not a single-shot socket.
- Credentials land in
.env.localor.env. The skill checks.gitignoreand adds the file if it is missing. - The key is organisation-scoped and revocable from the dashboard at any time.
- The key travels in a URL query string on a loopback redirect, which means it can reach your browser’s history. Rotate it if that matters to you.
Let a coding agent wire it up
The integration logic ships as a cross-agent skill bundle. Install it into Claude Code, Cursor, Codex or 50-odd other agents, then ask for /axonpush-integrate.
Supported frameworks
The 23 sub-skills in the axonpush bundle, agent frameworks, OpenTelemetry exporters and log forwarders, what each one wires up, and how detection picks between them.