# How to Configure Custom Output Directories for Audit Logs and Reports in Shannon

> Configure custom output directories for Shannon audit logs and reports using the OUTPUT flag. Streamline your workflow and manage logged data efficiently.

- Repository: [KeygraphHQ/shannon](https://github.com/keygraphhq/shannon)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Use the `OUTPUT=` flag when running the Shannon CLI to specify a custom host directory, which the system then bind-mounts to `/app/output` inside the Docker worker and propagates through the Temporal workflow to all audit-logging agents.**

Shannon, the automated penetration-testing framework by KeygraphHQ/shannon, generates extensive artefacts during every engagement—including raw tool output, agent logs, and final PDF reports. By default, the CLI writes these files to `./audit-logs/` at the repository root. However, production deployments often require redirecting this data to mounted network storage, CI/CD artefacts directories, or organised archival paths.

## Using the OUTPUT Flag in the Shannon CLI

The fastest way to configure a custom output directory is to append the `OUTPUT=` argument when invoking the Bash wrapper. The script validates the path, creates it if necessary, and ensures the Docker worker can write to it.

```bash

# Run a pentest and store all artefacts under ./my-reports/

./shannon start URL=https://example.com REPO=my-app OUTPUT=./my-reports

```

The `shannon` script performs three critical actions with this value:

1. **Creates the host directory** with `mkdir -p "$OUTPUT"` and sets permissions (`chmod 777`) so the container process can write to it.
2. **Exports `OUTPUT_DIR`** to the environment so Docker Compose can reference it.
3. **Mounts the volume** via `-v "$OUTPUT_DIR":/app/output` when starting the worker container.

After the workflow completes, the CLI prints the host-side path so you can locate the generated reports immediately:

```

Reports: ./my-reports/host-example.com_shannon-1708153456789

```

## How Custom Output Paths Flow Through the System

Understanding the data flow helps when debugging permission issues or when invoking components directly without the Bash wrapper. The path travels from the host CLI through Docker, into the Temporal workflow, and finally to the audit-logging utilities.

### CLI Argument Parsing and Docker Volume Mounting

In the `shannon` entrypoint script (lines 73‑78), the flag is parsed and stored in the `OUTPUT` variable. Lines 70‑74 and 92‑96 handle the Docker volume export:

```bash

# From shannon (lines 73-78)

OUTPUT=*)
  OUTPUT="${1#*=}"
  shift
  ;;

```

The script then ensures the directory exists and exports it for Docker Compose:

```bash
mkdir -p "$OUTPUT"
chmod 777 "$OUTPUT"
export OUTPUT_DIR="$OUTPUT"

```

### Temporal Client and Workflow Input

The Temporal client at [`src/temporal/client.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/temporal/client.ts) (lines 90‑96, 122‑126, and 148‑152) receives the host path via `--display-output` and the container-internal path via `--output`. It constructs a `PipelineInput` object defined in [`src/temporal/shared.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/temporal/shared.ts) (line 9):

```typescript
// From src/temporal/client.ts
if (outputPath) {
  // /app/output is the path inside the container
  ARGS += ` --output /app/output --display-output ${outputPath}`;
}

```

The `PipelineInput` interface includes the optional `outputPath` field:

```typescript
// From src/temporal/shared.ts (line 9)
interface PipelineInput {
  outputPath?: string;
  // ... other fields
}

```

### Audit Log Resolution in the Worker

Inside the workflow, agents invoke `getSessionDir` from [`src/audit/utils.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/audit/utils.ts) (line 23) to determine where to write logs. This function prefers the custom `outputPath` if provided, otherwise falling back to the default `AUDIT_LOGS_DIR` (`./audit-logs`):

```typescript
// From src/audit/utils.ts
export function getSessionDir(sessionMetadata: { outputPath?: string }) {
  // Prefer the custom path supplied by the workflow
  const baseDir = sessionMetadata.outputPath || AUDIT_LOGS_DIR;
  return path.join(baseDir, sessionMetadata.workflowId);
}

```

Because the Docker container bind-mounted the host directory to `/app/output`, and the workflow received `/app/output` as its `outputPath`, all file writes are immediately persisted to the host filesystem.

## Direct Temporal Client Invocation

For advanced use cases—such as integrating Shannon into existing CI pipelines—you may bypass the Bash wrapper and call the Temporal client directly. Ensure the Docker volume is already mounted before running this command:

```bash

# Equivalent call without the Bash wrapper

node dist/temporal/client.js \
  https://example.com /repos/my-app \
  --output /app/output \
  --display-output ./my-reports \
  --pipeline-testing

```

The `--output` flag must match the container-internal mount point (`/app/output`), while `--display-output` should reflect the host-side path for user feedback in logs.

## Key Implementation Files

| File | Purpose | Relevant lines |
|------|---------|----------------|
| `shannon` (Bash CLI) | Parses `OUTPUT=` flag, creates host directory, exports `OUTPUT_DIR`, starts containers, forwards flags to client. | 73‑78, 90‑96, 122‑126, 148‑152 |
| [`src/temporal/client.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/temporal/client.ts) | Temporal client that receives `--output` and `--display-output`, builds `PipelineInput` for the workflow. | 90‑96, 122‑126, 148‑152 |
| [`src/temporal/shared.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/temporal/shared.ts) | Defines `PipelineInput.outputPath` which propagates through the workflow. | 9‑10 |
| [`src/audit/utils.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/audit/utils.ts) | Resolves the final output directory, using the custom `outputPath` if present. | 23‑27 |
| [`src/cli/ui.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/cli/ui.ts) | Prints usage help that mentions the `--output` flag. | 23‑25 |

## Summary

- **Default behavior**: Shannon writes all artefacts to `./audit-logs/` at the repository root.
- **Custom configuration**: Append `OUTPUT=<host-path>` to the `./shannon start` command to redirect output anywhere on the host filesystem.
- **Mechanism**: The Bash wrapper bind-mounts your directory to `/app/output` inside the Docker worker, then passes that path through the Temporal workflow to [`src/audit/utils.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/audit/utils.ts), which uses it as the base directory for all session logs and reports.
- **Direct usage**: When calling [`src/temporal/client.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/temporal/client.ts) directly, use `--output /app/output` (container path) and `--display-output <host-path>` (user feedback).

## Frequently Asked Questions

### What is the default output directory if I don't specify OUTPUT=?

If you omit the `OUTPUT=` flag, Shannon defaults to `./audit-logs/` relative to the repository root. This path is defined as `AUDIT_LOGS_DIR` in [`src/audit/utils.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/audit/utils.ts) and is used whenever `sessionMetadata.outputPath` is undefined.

### Can I use absolute paths with the OUTPUT flag?

Yes. The `shannon` script accepts both relative and absolute paths. It runs `mkdir -p "$OUTPUT"` to ensure the directory exists, then exports it as `OUTPUT_DIR` for the Docker volume mount. Absolute paths work identically to relative ones, making them ideal for CI/CD environments where the working directory may vary.

### How do I ensure the Docker container can write to my custom directory?

The `shannon` wrapper automatically sets `chmod 777 "$OUTPUT"` on the host directory before mounting it. This ensures the container process (which may run as a different UID) has write access. If you invoke the Temporal client directly without the wrapper, you must manually ensure the directory permissions allow the container user to write to the bind-mounted path.

### Is the output path configuration persistent across Shannon runs?

No. The `OUTPUT=` flag is ephemeral to the specific invocation. Each time you run `./shannon start`, you must specify the desired output directory. For persistent configuration, you can create a shell alias or wrapper script that always appends your preferred `OUTPUT=` value to the command, or you can modify the default constant `AUDIT_LOGS_DIR` in [`src/audit/utils.ts`](https://github.com/KeygraphHQ/shannon/blob/main/src/audit/utils.ts) before building the project.