# How it Works

Ax doesn't have any APIs; it's purely a command-line tool. Moreover, Ax doesn't even interact with any cloud provider's APIs directly. Instead, Ax wraps the cloud provider's CLI to perform cloud operations, simplifying the process. By wrapping the cloud provider's CLI, we eliminate the need to write API calls for each operation, abstracting some complexity.&#x20;

The cloud provider CLI functions are stored in [`~/.axiom/providers`](https://github.com/attacksurge/ax/tree/master/providers).

## Installation Flow

{% hint style="info" %}
**Quick Breakdown:** During the first time install, `ax configure` calls `ax account-setup`, then `ax account`and finally `ax build`. This installs all required dependencies, installs and authenticates the cloud providers CLI, and kicks off the Packer builder to create an image with your desired tools installed.
{% endhint %}

When you setup the Ax Controller on a [supported OS](/overview/installation-guide.md#supported-os), the required dependencies are first installed.

<figure><img src="/files/LXGcC48T115G1Ux8WAX6" alt=""><figcaption><p>bash &#x3C;(curl -s https://raw.githubusercontent.com/attacksurge/ax/master/interact/axiom-configure) --run</p></figcaption></figure>

Then you pick what shell you'd like to use, either bash, zsh or oh my zsh

<figure><img src="/files/oHKreq4PjtuvjXcSoiGl" alt=""><figcaption><p>ax configure --run</p></figcaption></figure>

You'll have an option to install Golang (not required).

<figure><img src="/files/JsQ5hcA1clEH3lDhrZcj" alt=""><figcaption><p>ax configure --run</p></figcaption></figure>

Then `ax configure` kicks off `ax account-setup,` where you decide what cloud provider to use.&#x20;

<figure><img src="/files/bb30ukQS1L6PRXvQ2g1S" alt=""><figcaption><p>ax account</p></figcaption></figure>

When you select a cloud provider, `ax account-setup` calls the associated cloud provider's [account-helpers](https://github.com/attacksurge/ax/tree/main/interact/account-helpers) script. This script installs and setups the CLI and Ax account profile.

After providing a valid authentication token, you select the region where you want to deploy, along with the desired instance size (CPU, RAM).  Finally, you choose a name for the Ax account profile, which **stores your cloud account credentials** and other user profile information in `~/.axiom/accounts/$profile-name.json`.

<figure><img src="/files/ny08AQNq1DfM3ZxYZhWq" alt=""><figcaption><p>ax provider</p></figcaption></figure>

{% hint style="info" %}
**Symbolic Links:** Ax supports multiple account user profiles. To list your current account user profiles, use [ax account](https://github.com/attacksurge/ax/blob/master/interact/axiom-account). To switch between different profiles, use ax account $profile.&#x20;

For example, running `ax account do` switches to my Digital Ocean user profile.&#x20;

**cloud credentials** and user profile data are stored in **`~/.axiom/accounts/$profile-name.json`**. A symbolic link to this file is created in **`~/.axiom/axiom.json`**.

Another important aspect of [`ax account`](https://github.com/attacksurge/ax/blob/master/interact/axiom-account) is that it calls [`ax provider`](https://github.com/attacksurge/ax/blob/master/interact/axiom-provider).

`ax provider` creates another symbolic link from the [cloud providers functions ](https://github.com/attacksurge/ax/tree/master/providers)in `~/.axiom/providers/$cloud-provider.sh` to `~/.axiom/interact/includes/functions.sh`

This dynamic linking is how Ax remains flexible. When you switch accounts, the appropriate [cloud provider functions](https://github.com/attacksurge/ax/tree/master/providers) and [user profile](https://github.com/attacksurge/ax/blob/master/accounts/do.json.example) are essentially sourced.
{% endhint %}

ax account-setup then calls ax build. ax build creates the Packer image based on the Provisioner file chosen.

After choosing your Provisioner, Packer creates a temporary cloud instance, installs all the tools found in the Provisioner file, takes a snapshot of the image and saves it. Then Packer deletes the temporary instance.&#x20;

{% hint style="info" %}
`ax build` combines the cloud provider's Builder (either [JSON](https://github.com/attacksurge/ax/tree/master/images/json/builders) or [HCL](https://github.com/attacksurge/ax/tree/master/images/pkr.hcl/builders)) file with a Provisioner (also either [JSON](https://github.com/attacksurge/ax/tree/master/images/json/provisioners) or [HCL](https://github.com/attacksurge/ax/tree/master/images/pkr.hcl/provisioners)) file into the final Packer file, which is stored in `~/.axiom/images/$format/axiom.json`&#x20;
{% endhint %}

<figure><img src="/files/wn9C8WIXwwHYgEMcTgAo" alt=""><figcaption><p>ax build barebones</p></figcaption></figure>

{% hint style="info" %}
**SSH Keys:** By default, ax creates a SSH key named axiom\_rsa in `~/.ssh/axiom_rsa`. The reference to the SSH key is stored in `~/.axiom/axiom.json`. You can change the`sshkey` value to another SSH key as long as its stored in `~/.ssh/`.&#x20;

You might need to rebuild (ax build) with your new SSH key to use it.
{% endhint %}

When the build completes you should see a success message like the one below. You might need to restart your shell.

<figure><img src="/files/DI0Rjrl2ksLHAKWMT6PJ" alt=""><figcaption><p>ax build barebones</p></figcaption></figure>

## Ax SSH Config

Ax creates its own sshconfig located in `~/.axiom/.sshconfig`

The sshconfig is how the Ax Controller communicates to the Ax instances (fleets).

The sshconfig is generated based on your cloud inventory and allows you to connect to your Ax instances over their public or private network interface. Most Ax scripts generate a fresh SSH config before executing. You can always regenerate the sshconfig manually with `ax ssh --just-generate` or lock the sshconfig to prevent Ax from ever regenerating `ax ssh --just-generate lock`. To unlock the sshconfig run `ax ssh --just-generate`

{% hint style="info" %}
**Private Network Connectivity:** When creating the sshconfig from instances private IPs (ax ssh --just-generate private) you must be on the same private network as your cloud instances. &#x20;
{% endhint %}

## ax scan

After you spin up some instances, you can run `ax scan` to perform a distributed scan using those instances (fleet).

{% hint style="info" %}
**ax scan:** for a detailed overview on ax scan, please visit <https://ax-framework.gitbook.io/wiki/fundamentals/scan>
{% endhint %}

<figure><img src="/files/KqxILXuCwZQHT03RpFl9" alt=""><figcaption><p>ax fleet -i 5</p></figcaption></figure>

The first argument passed to `ax scan` must always be an input file (bunch of IPs or URLs etc).\
`ax scan` takes a user provided input file and divides the input file by how many instances currently selected (`ax select`).&#x20;

In this case, we have a target list of five lines and five instances selected. So each instance will scan one target. You can also pass additional arguments to the underlying module by simply appending them to the command line.&#x20;

{% hint style="info" %}
**Modules:** For a detailed overview on ax scan modules, please visit <https://ax-framework.gitbook.io/wiki/fundamentals/scan>[/modules](/fundamentals/scans/modules.md)&#x20;
{% endhint %}

<figure><img src="/files/ObO5oorTKVl7BBovR7uN" alt=""><figcaption><p>ax scan input -m dnsx -o dnsx-results --silent</p></figcaption></figure>

`ax scan` begins by using SSH to create a scan working directory on the remote instances at `/home/op/scan/$module-$timestamp/`. You can see what `ax scan` uploads by using `ax ssh` to connect to any instance and navigating to the scan working directory on the remote instance.

When an instance completes its operation, Ax creates a file named after the instance's hostname in the scan working directory on the remote instance. Ax continuously checks for these hostname files to determine the completion status of all instances. Once all instances have created their hostname files, or if Ax can no longer reach any of the instances, the scan is considered complete. Scan results are periodically downloaded throughout the process and once again when the scan finishes.

<figure><img src="/files/9mSVg91vXOLu6Qr8s1dp" alt=""><figcaption><p>ax ssh</p></figcaption></figure>

During the scan, you can view the results periodically downloaded to `~/axiom/tmp/$module+$timestamp/`. Once the scan is complete, the results from all scanners are merged and moved to `~/axiom/logs/$module+$timestamp/`.

You can check which instances have completed their scans by navigating to the local temporary scan directory and displaying the contents of `status/completed/hosts`.

<figure><img src="/files/9wCDXfHchozygTqJGRZP" alt=""><figcaption><p>cat /home/user/.axiom/tmp/nmapx+172203724417078/status/completed/hosts</p></figcaption></figure>

You can also monitor any instance in real-time by using `ax ssh` to connect and attach to the tmux session. A unique tmux session, named `$module+$timestamp`, is created on each remote instance to manage the scan.

<figure><img src="/files/5KIaGRKyQRiWWOj6wMK4" alt=""><figcaption><p>tmux a -t $module+$timestamp</p></figcaption></figure>

## More Info

In summary, Ax simplifies the distribution of arbitrary binaries and scripts by configuring your cloud account CLI, building Packer images, and deploying fleets of new instances. It dynamically splits and uploads an input file to all selected instances, executing the same command across each one. Upon completing the scan, Ax downloads and merges the scan output.

For more information, continue to [Ax Utility Scripts](/fundamentals/ax-utility-scripts.md) or [Scans](/fundamentals/scans.md)!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ax.attacksurge.com/overview/how-it-works.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
