# How API Security Works in AUTOMATIC1111: Authentication and Request Validation

> Learn how AUTOMATIC1111 secures its API with HTTP Basic Authentication and runtime request validation, protecting your stable diffusion web UI.

- Repository: [AUTOMATIC1111/stable-diffusion-webui](https://github.com/AUTOMATIC1111/stable-diffusion-webui)
- Tags: how-to-guide
- Published: 2026-02-24

---

**AUTOMATIC1111 secures its FastAPI-based REST API through optional HTTP Basic Authentication configured via `--api-auth` and request validation that filters sensitive parameters and blocks local network requests using runtime flags.**

The AUTOMATIC1111/stable-diffusion-webui repository exposes a REST API at `/sdapi/v1/...` for programmatic access to Stable Diffusion generation features. Understanding how API security works in AUTOMATIC1111 is essential before exposing the service to networks beyond localhost, as the implementation combines credential-based access control with strict input sanitization to prevent unauthorized usage and server-side request forgery (SSRF).

## Authentication Layer

The WebUI implements HTTP Basic Authentication as an optional but recommended security boundary. When enabled, every API endpoint requires valid credentials passed in the `Authorization` header, with passwords validated using constant-time comparison to prevent timing attacks.

### Enabling HTTP Basic Authentication

Authentication is configured at startup using command-line arguments defined in [`modules/cmd_args.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/cmd_args.py). You can pass credentials directly or load them from a file:

```bash

# Single user

python webui.py --api-auth username:password

# Multiple users

python webui.py --api-auth user1:pass1,user2:pass2

# From file

python webui.py --api-auth-path /path/to/credentials.txt

```

In [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py), the `Api` class constructor parses these credentials into a dictionary during initialization:

```python
if shared.cmd_opts.api_auth:
    for auth in shared.cmd_opts.api_auth.split(","):
        user, password = auth.split(":")
        self.credentials[user] = password

```

### The Authentication Flow

When `--api-auth` is present, the `add_api_route` method registers every endpoint with a FastAPI dependency on `self.auth`:

```python
if shared.cmd_opts.api_auth:
    return self.app.add_api_route(path, endpoint,
                                 dependencies=[Depends(self.auth)], **kwargs)

```

The `auth` method itself, implemented in [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py), uses FastAPI's `HTTPBasic` scheme and `secrets.compare_digest` for secure comparison:

```python
def auth(self, credentials: HTTPBasicCredentials = Depends(HTTPBasic())):
    if credentials.username in self.credentials:
        if secrets.compare_digest(credentials.password, 
                                  self.credentials[credentials.username]):
            return True
    raise HTTPException(
        status_code=401, 
        detail="Incorrect username or password",
        headers={"WWW-Authenticate": "Basic"}
    )

```

If no `--api-auth` flag is provided, the API operates in open mode, suitable only for trusted local networks.

## Request Validation and Input Sanitization

Beyond authentication, the API validates incoming payloads to prevent parameter injection and restricts external HTTP requests to mitigate SSRF vulnerabilities.

### Pydantic Model Whitelisting

The API dynamically generates Pydantic models from internal processing classes (`StableDiffusionProcessingTxt2Img`, `StableDiffusionProcessingImg2Img`) but explicitly excludes dangerous fields. In [`modules/api/models.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/models.py), the `API_NOT_ALLOWED` list defines prohibited parameters:

```python
API_NOT_ALLOWED = [
    "self", "kwargs", "sd_model", "outpath_samples", "outpath_grids",
    "sampler_index", "extra_generation_params", "overlay_images",
    "do_not_reload_embeddings", "seed_enable_extras", "prompt_for_display",
    "sampler_noise_scheduler_override", "ddim_discretize"
]

```

During model generation, the `PydanticModelGenerator` skips these fields, ensuring API consumers cannot override internal file paths, change model storage locations, or access restricted generation parameters.

### Image URL Validation and SSRF Protection

When processing base64-encoded images or remote URLs in [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py), the `decode_base64_to_image` function implements two critical runtime checks stored in the global `opts` object ([`modules/shared.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/shared.py)):

- **`opts.api_enable_requests`**: Master switch for all external HTTP GET requests (default `True`)
- **`opts.api_forbid_local_requests`**: Blocks requests to private IP ranges when `True` (default `True`)

The validation logic resolves hostnames and rejects non-global addresses:

```python
def decode_base64_to_image(encoding):
    if encoding.startswith("http://") or encoding.startswith("https://"):
        if not opts.api_enable_requests:
            raise HTTPException(500, "Requests not allowed")
        if opts.api_forbid_local_requests and not verify_url(encoding):
            raise HTTPException(500, "Request to local resource not allowed")
        # ... proceed with request

```

The `verify_url` helper ensures every resolved IP is global (not private, loopback, or link-local), preventing attackers from using the API to probe internal network services.

## Security Configuration Options

All security parameters are configurable via CLI flags at startup:

| Flag | Purpose | Default |
|------|---------|---------|
| `--api-auth` | Sets username:password pairs for Basic Auth | None (open) |
| `--api-auth-path` | Loads credentials from a file | None |
| `--api-enable-requests` | Allows external HTTP requests for images | `True` |
| `--api-forbid-local-requests` | Blocks requests to local/private IPs | `True` |

These values persist in `shared.opts` and are accessible throughout the application lifecycle.

## Practical Implementation Examples

### Authenticated Text-to-Image Request

Call the txt2img endpoint with Basic Auth credentials:

```bash
curl -X POST "http://127.0.0.1:7860/sdapi/v1/txt2img" \
     -u alice:SecretPass \
     -H "Content-Type: application/json" \
     -d '{
           "prompt": "a cyberpunk city at sunset",
           "steps": 30,
           "cfg_scale": 7,
           "width": 512,
           "height": 512,
           "sampler_index": "Euler",
           "send_images": true
         }' | jq .

```

The `-u` flag generates the `Authorization: Basic` header that the `auth` method validates against the credentials supplied via `--api-auth`.

### Submitting Remote Images with URL Validation

For img2img operations using external images:

```bash
curl -X POST "http://127.0.0.1:7860/sdapi/v1/img2img" \
     -u admin:Pass123 \
     -H "Content-Type: application/json" \
     -d '{
           "init_images": ["https://example.com/public/photo.jpg"],
           "prompt": "portrait in the style of Van Gogh",
           "denoising_strength": 0.6,
           "steps": 20
         }' | jq .

```

Under the hood, `decode_base64_to_image` checks `opts.api_enable_requests` and `opts.api_forbid_local_requests`, then calls `verify_url` to ensure `example.com` resolves to a global IP address before fetching the resource.

### Hardening Against External Requests

To completely disable remote image fetching and prevent SSRF attacks:

```bash
python webui.py --api-auth admin:StrongPwd \
                --api-enable-requests=False \
                --api-forbid-local-requests=True

```

Any request containing an external URL now returns:

```json
{
  "error": "HTTPException",
  "detail": "Requests not allowed"
}

```

## Summary

- **Authentication is opt-in**: Use `--api-auth` to enable HTTP Basic Authentication via [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py), storing credentials in `self.credentials` and validating with `secrets.compare_digest`.
- **Parameter filtering is automatic**: The `API_NOT_ALLOWED` whitelist in [`modules/api/models.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/models.py) prevents API consumers from setting internal paths or restricted generation parameters.
- **SSRF protection is runtime-configurable**: The `decode_base64_to_image` function in [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py) uses `verify_url` and `opts.api_forbid_local_requests` to block requests to local network resources.
- **Security flags are centralized**: All settings are defined in [`modules/cmd_args.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/cmd_args.py) and stored in [`modules/shared.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/shared.py)'s global `opts` object.

## Frequently Asked Questions

### Is the AUTOMATIC1111 API open by default?

Yes. Unless you explicitly provide the `--api-auth` command-line argument, the REST API endpoints in [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py) do not require authentication, making them accessible to any client that can reach the server. You should only run without authentication on trusted local networks.

### How does the API prevent server-side request forgery (SSRF)?

The `decode_base64_to_image` function checks `opts.api_forbid_local_requests` (default `True`) and calls `verify_url` to resolve hostnames and validate that target IPs are global addresses. Requests to private ranges (10.0.0.0/8, 192.168.0.0/16), loopback (127.0.0.1), or link-local addresses are rejected with a 500 error before any HTTP request is executed.

### Which internal parameters are blocked from API access?

The `API_NOT_ALLOWED` list in [`modules/api/models.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/models.py) excludes sensitive fields such as `sd_model`, `outpath_samples`, `outpath_grids`, `sampler_index`, and `sampler_noise_scheduler_override` from the dynamically generated Pydantic models. This prevents API users from changing model storage paths or overriding internal generation settings.

### Can I load authentication credentials from a file instead of the command line?

Yes. Use the `--api-auth-path` flag to specify a text file containing username:password pairs. The startup logic in [`modules/api/api.py`](https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/main/modules/api/api.py) reads this file and populates `self.credentials` identically to the `--api-auth` flag, keeping sensitive credentials out of process lists and shell history.