# Service Routes

Service routes define how Atlas Auth Guard proxies requests to backend microservices. They act as the configuration layer for the API gateway functionality.

***

## What is a Service Route?

A service route maps a URL path to a backend service:

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                        SERVICE ROUTING                                       │
└─────────────────────────────────────────────────────────────────────────────┘

  Client Request                 Auth Guard                    Backend Service
  ══════════════                 ══════════                    ═══════════════

  GET /v1/llm/generate    →    Route: "llm"           →    https://llm-svc.run.app
                               url: llm-svc.run.app          /api/v1/generate
                               api_path: /api/v1

  POST /v1/oss/objects    →    Route: "oss"           →    https://oss-svc.run.app
                               url: oss-svc.run.app          /oss/objects
                               api_path: (none)

  GET /v1/cot/reason      →    Route: "cot"           →    https://cot-svc.run.app
                               url: cot-svc.run.app          /api/v1/reason
                               api_path: /api/v1
```

***

## Route Configuration

Each route has the following configuration:

### Basic Settings

| Field           | Description                         | Example                          |
| --------------- | ----------------------------------- | -------------------------------- |
| **name**        | Route identifier (used in URL path) | `llm`, `cot`, `atlas-al-oss-svc` |
| **url**         | Backend service base URL            | `https://llm-svc-xxx.run.app`    |
| **description** | Human-readable description          | `LLM text generation service`    |
| **enabled**     | Whether route is active             | `true` / `false`                 |

### Path Configuration

| Field                    | Description               | Example                 |
| ------------------------ | ------------------------- | ----------------------- |
| **api\_path**            | Base path on backend      | `/api/v1`               |
| **path\_transformation** | How to transform the path | `strip_prefix` / `none` |

### Quota Settings

| Field            | Description                | Example        |
| ---------------- | -------------------------- | -------------- |
| **quota\_limit** | Max requests per time unit | `500`          |
| **quota\_unit**  | Time unit for quota        | `requests/min` |

### Documentation Endpoints

| Field                 | Description       | Example         |
| --------------------- | ----------------- | --------------- |
| **health\_endpoint**  | Health check path | `/health`       |
| **docs\_endpoint**    | Swagger UI path   | `/docs`         |
| **redoc\_endpoint**   | ReDoc path        | `/redoc`        |
| **openapi\_endpoint** | OpenAPI JSON path | `/openapi.json` |

***

## Path Transformation

Path transformation controls how the URL path is modified before forwarding to the backend.

### `strip_prefix` (Default)

Removes `/v1/{service_name}` and prepends `api_path`:

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  strip_prefix TRANSFORMATION                                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  Route Config:                                                               │
│    name: llm                                                                 │
│    url: https://llm-svc.run.app                                              │
│    api_path: /api/v1                                                         │
│    path_transformation: strip_prefix                                         │
│                                                                              │
│  Request:  GET /v1/llm/generate?prompt=hello                                 │
│                    ▼                                                         │
│  Strip:    /v1/llm removed → /generate?prompt=hello                          │
│                    ▼                                                         │
│  Prepend:  /api/v1 added → /api/v1/generate?prompt=hello                     │
│                    ▼                                                         │
│  Forward:  GET https://llm-svc.run.app/api/v1/generate?prompt=hello          │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
```

### `none`

Just removes `/v1/{service_name}`, doesn't prepend anything:

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  none TRANSFORMATION                                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  Route Config:                                                               │
│    name: atlas-al-oss-svc                                                    │
│    url: https://oss-svc.run.app                                              │
│    api_path: (empty)                                                         │
│    path_transformation: none                                                 │
│                                                                              │
│  Request:  GET /v1/atlas-al-oss-svc/oss/objects?prefix=test                  │
│                    ▼                                                         │
│  Strip:    /v1/atlas-al-oss-svc removed → /oss/objects?prefix=test           │
│                    ▼                                                         │
│  Forward:  GET https://oss-svc.run.app/oss/objects?prefix=test               │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
```

***

## Headers Injected by Auth Guard

When Auth Guard proxies a request, it injects headers containing the authenticated user's context:

### User Context Headers

| Header         | Description              | Example                                |
| -------------- | ------------------------ | -------------------------------------- |
| `X-User-ID`    | User's unique identifier | `e9f7fca6-65d3-4be0-8374-07870b789a28` |
| `X-User-Email` | User's email address     | `alice@turing.com`                     |
| `X-User-Name`  | User's display name      | `Alice Smith`                          |

### Organization Context Headers

| Header       | Description             | Example                                |
| ------------ | ----------------------- | -------------------------------------- |
| `X-Org-ID`   | Organization identifier | `4047160a-abb2-497c-bf0c-3f4ab7cb0b16` |
| `X-Org-Name` | Organization name       | `Turing`                               |

### Team Context Headers

| Header        | Description     | Example                                |
| ------------- | --------------- | -------------------------------------- |
| `X-Team-ID`   | Team identifier | `ab2785b2-b5d0-4926-92fb-00aae5ec860a` |
| `X-Team-Name` | Team name       | `Engineering`                          |

### Project Context Headers

| Header           | Description        | Example                                |
| ---------------- | ------------------ | -------------------------------------- |
| `X-Project-ID`   | Project identifier | `5ac942ba-0290-48a7-be6e-7ea58cd40b68` |
| `X-Project-Name` | Project name       | `LLM API`                              |

### Role & Permission Headers

| Header             | Description               | Example                             |
| ------------------ | ------------------------- | ----------------------------------- |
| `X-Global-Role`    | User's global role (raw)  | `member`                            |
| `X-Team-Role`      | User's team role (raw)    | `team_admin`                        |
| `X-Project-Role`   | User's project role (raw) | `editor`                            |
| `X-Effective-Role` | Calculated effective role | `editor`                            |
| `X-Permissions`    | JSON array of permissions | `["read:project", "write:project"]` |

### Tracing Headers

| Header         | Description               | Example                                |
| -------------- | ------------------------- | -------------------------------------- |
| `X-Request-ID` | Unique request identifier | `040d556a-8dd4-4ee1-8800-8cf4e11bcd0d` |

### Backend Service Usage

Backend services should use these headers for:

```python
# Authorization decisions
@app.get("/sensitive-data")
async def get_sensitive_data(
    x_effective_role: str = Header(...),
    x_permissions: str = Header(...)
):
    permissions = json.loads(x_permissions)
    if "read:sensitive" not in permissions:
        raise HTTPException(403, "Not authorized")
    return data

# Data filtering
@app.get("/objects")
async def list_objects(x_project_id: str = Header(...)):
    # CRITICAL: Filter by project
    return db.query(Object).filter(
        Object.project_id == x_project_id
    ).all()

# Audit logging
@app.post("/actions")
async def perform_action(
    x_user_id: str = Header(...),
    x_user_email: str = Header(...),
    x_request_id: str = Header(...)
):
    logger.info(f"Action by {x_user_email}", extra={
        "user_id": x_user_id,
        "request_id": x_request_id
    })
```

***

## Documentation Proxy

Auth Guard can proxy documentation endpoints from backend services, providing a unified documentation experience:

### Available Documentation URLs

| URL Pattern                  | Description           |
| ---------------------------- | --------------------- |
| `/v1/{service}/docs`         | Swagger UI            |
| `/v1/{service}/redoc`        | ReDoc documentation   |
| `/v1/{service}/openapi.json` | OpenAPI specification |
| `/v1/{service}/health`       | Health check          |

### Example

```
https://auth-gw.atlas.turing.com/v1/llm/docs
    ↓
Proxies to: https://llm-svc.run.app/docs
```

This allows users to access backend service documentation without direct backend access.

***

## Current Routes (Production)

| Service Name       | Path Pattern             | Backend         | Description            |
| ------------------ | ------------------------ | --------------- | ---------------------- |
| `atlas-al-oss-svc` | `/v1/atlas-al-oss-svc/*` | asia-southeast1 | Alibaba OSS Gateway    |
| `cli-eval`         | `/v1/cli-eval/*`         | -               | CLI Evaluation Service |
| `llm`              | `/v1/llm/*`              | -               | LLM Text Generation    |
| `cot`              | `/v1/cot/*`              | -               | Chain of Thought       |
| `auto-rater`       | `/v1/auto-rater/*`       | -               | Content Rating         |

***

## Admin Dashboard

Access route management at: `/admin/routes`

### Route List View

| Column     | Description              |
| ---------- | ------------------------ |
| **Name**   | Route identifier         |
| **URL**    | Backend service URL      |
| **Status** | enabled/disabled         |
| **Health** | Current health status    |
| **Quota**  | Rate limit configuration |

### Route Actions

| Action             | Description                   |
| ------------------ | ----------------------------- |
| **Create**         | Add new service route         |
| **Edit**           | Modify route configuration    |
| **Enable/Disable** | Toggle route without deleting |
| **Delete**         | Remove route permanently      |
| **Health Check**   | Test route connectivity       |

***

## Best Practices

### Route Configuration

| Practice                       | Reason                   |
| ------------------------------ | ------------------------ |
| **Use descriptive names**      | `llm-service` not `svc1` |
| **HTTPS only**                 | Security requirement     |
| **Configure health endpoints** | Enable monitoring        |
| **Set appropriate quotas**     | Prevent abuse            |

### Security

| Practice                        | Reason                  |
| ------------------------------- | ----------------------- |
| **Private backend URLs**        | Services in VPC         |
| **Don't expose internal paths** | Use path transformation |
| **Monitor route usage**         | Detect anomalies        |

### Operations

| Practice                    | Reason               |
| --------------------------- | -------------------- |
| **Test before enabling**    | Verify configuration |
| **Disable before deleting** | Safe rollback        |
| **Document route purpose**  | Team knowledge       |

***

## Troubleshooting

### "Service not found" (404)

**Causes:**

* Route name doesn't match URL path
* Route doesn't exist
* Route is disabled

**Solutions:**

1. Check exact service name in URL
2. Verify route exists in dashboard
3. Enable route if disabled

### "Bad Gateway" (502)

**Causes:**

* Backend service is down
* Backend URL is incorrect
* Network/firewall issues

**Solutions:**

1. Check backend service health
2. Verify URL in route configuration
3. Check Cloud Run logs

### "Gateway Timeout" (504)

**Causes:**

* Backend is too slow
* Request/response too large
* Backend overloaded

**Solutions:**

1. Optimize backend performance
2. Increase timeout if needed
3. Scale backend service
