# How the Dashboard Secures File Access Using Path Allowlists and Tokens

> Learn how the Understand-Anything dashboard secures file access with path allowlisting and tokens. Protect your project data with our robust security features.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: security
- Published: 2026-06-23

---

**The Understand-Anything dashboard protects file access through a dual-layer mechanism combining a cryptographically secure one-time token generated at server startup and a strict path allowlist derived from the project's knowledge graph, ensuring only analyzed project files are accessible to authenticated clients.**

The Egonex-AI/Understand-Anything repository includes a React-based dashboard that exposes sensitive source code through a development server. To prevent unauthorized access and directory traversal attacks, the file-viewer endpoint implements a hardened security model that validates every request against both a secret token and a curated list of allowed paths.

## The Two-Layer Security Architecture

The [`/file-content.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main//file-content.json) endpoint in [`vite.config.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/vite.config.ts) enforces two complementary validation steps before serving any file content.

### One-Time Access Token Generation

At server startup, the middleware generates a 32-character hexadecimal token using `crypto.randomBytes(16).toString("hex")`, or loads a custom value from the `UNDERSTAND_ACCESS_TOKEN` environment variable.

```typescript
// vite.config.ts – lines 9-13
const ACCESS_TOKEN = process.env.UNDERSTAND_ACCESS_TOKEN || 
                     crypto.randomBytes(16).toString("hex");

```

This token is printed in the terminal as part of the dev server URL, ensuring only the developer who started the server can construct valid requests.

### Graph-Derived Path Allowlist

The second layer restricts access to files explicitly discovered during the analysis phase. After running `/understand`, the system generates a [`knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/knowledge-graph.json) file in the `.understand-anything/` directory containing metadata for every source file in the project.

The `graphFilePathSet` function parses this JSON and builds a `Set` of normalized relative paths:

```typescript
// vite.config.ts – lines 55-70
function graphFilePathSet(graphFile: string, projectRoot: string): Set<string> {
  const allowed = new Set<string>();
  const raw = JSON.parse(fs.readFileSync(graphFile, "utf-8"));
  for (const node of raw.nodes ?? []) {
    if (typeof node.filePath !== "string") continue;
    const normalized = normalizeGraphPath(node.filePath, projectRoot);
    if (normalized) allowed.add(normalized);
  }
  return allowed;
}

```

## Token Validation Workflow

Every request to protected endpoints—including [`/file-content.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main//file-content.json) and [`/knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main//knowledge-graph.json)—passes through middleware that validates the `token` query parameter against the server-side `ACCESS_TOKEN` constant.

If the tokens mismatch, the server immediately returns **403 Forbidden**:

```typescript
// vite.config.ts – lines 63-68
if (url.searchParams.get("token") !== ACCESS_TOKEN) {
  sendJson(res, 403, { error: "Forbidden: missing or invalid token" });
  return;
}

```

The **React** `CodeViewer` component constructs request URLs by appending both the `token` and `path` parameters:

```typescript
// CodeViewer.tsx – lines 26-29
function fileContentUrl(filePath: string, token: string): string {
  const params = new URLSearchParams({ token, path: filePath });
  return `/file-content.json?${params.toString()}`;
}

```

## Path Normalization and Allowlist Enforcement

When `readSourceFile` handles a request, it sanitizes the input path, resolves it against the project root, and converts it to a forward-slash-separated relative path before checking against the allowlist.

If the normalized path is not present in the `graphFilePathSet`, the server returns **404 File not in the knowledge graph**:

```typescript
// vite.config.ts – path validation logic
const safeRelativePath = relativeToRoot.split(path.sep).join("/");
if (!graphFilePathSet(graphFile, projectRoot).has(safeRelativePath)) {
  return rejectFileRequest("File is not in the knowledge graph", 404);
}

```

This prevents directory traversal attacks and ensures the dashboard cannot leak files outside the analyzed project scope, such as system files or sensitive configuration files located elsewhere on the filesystem.

## Summary

- **The Understand-Anything dashboard** implements a hardened file access system in [`vite.config.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/vite.config.ts) to protect the [`/file-content.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main//file-content.json) endpoint.
- **One-time token generation** uses `crypto.randomBytes(16)` to create a cryptographically secure access token at server startup, or accepts a custom token via `UNDERSTAND_ACCESS_TOKEN`.
- **Graph-derived allowlist** builds a `Set` of normalized paths from [`knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/knowledge-graph.json), ensuring only files discovered during analysis are accessible.
- **Dual validation** requires both the correct token (returning 403 if missing) and an allowed path (returning 404 if not in the graph).
- **Client integration** in [`CodeViewer.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/CodeViewer.tsx) automatically appends the token to all file requests, seamlessly authenticating the React frontend with the dev server.

## Frequently Asked Questions

### What happens if I request a file without the token?

The server returns a **403 Forbidden** response. The middleware in [`vite.config.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/vite.config.ts) (lines 63-68) checks every protected request for the `token` query parameter and rejects any request where the value does not match the `ACCESS_TOKEN` generated at startup.

### Can the dashboard access files outside the project directory?

No. The `graphFilePathSet` function explicitly restricts access to files listed in [`knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/knowledge-graph.json). Even if a path is provided with a valid token, the server normalizes the request and checks it against the allowlist, returning **404 File not in the knowledge graph** if the file was not discovered during the analysis phase.

### How do I set a custom access token instead of the random one?

Set the `UNDERSTAND_ACCESS_TOKEN` environment variable before starting the dev server. If this variable is present, the code in [`vite.config.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/vite.config.ts) uses it instead of generating a new random token with `crypto.randomBytes(16)`, allowing you to use predictable tokens in automated testing or CI environments.

### Where does the path allowlist come from?

The allowlist originates from the [`knowledge-graph.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/knowledge-graph.json) file generated in the `.understand-anything/` directory after running the analysis command. The `graphFilePathSet` function extracts every `filePath` property from the graph nodes, normalizes them relative to the project root, and stores them in a `Set` for constant-time lookup during request validation.