# Chapter 4 — Architecture and Authentication

This chapter describes the authentication and authorization model used across the entire BR-UTM ecosystem, including how your USS obtains tokens, uses them to call DECEA's APIs, validates tokens received from other USSs, and authenticates peer-to-peer calls.

---

## 4.1 Authentication Architecture Overview

BR-UTM uses **OAuth2 Client Credentials flow** with **JWT (JSON Web Token) access tokens**, signed using **RS256 (RSA SHA-256)**. This is a stateless, distributed authentication model where:

1. Your USS presents its **API Key** to DECEA's **Auth Server** to obtain a signed JWT.
2. The JWT is included as a **Bearer token** in every API request (to the DSS, to DECEA's USS, or to other USSs).
3. The receiving server **validates the JWT locally** using DECEA's public key — it does not need to call the Auth Server again.

This architecture is critical for the distributed, peer-to-peer nature of the system: there is no central session state, and any server can independently validate any token.

```
┌──────────────────┐   1. POST /token?apikey=...&scope=...&intended_audience=...
│   Your USS       │──────────────────────────────────────────────────────────────►│ Auth Server │
│                  │◄──────────────────────────────── 2. JWT (signed RS256) ───────│             │
│                  │
│                  │   3. Authorization: Bearer <JWT>
│                  │──────────────────────────────────────────────────────────────►│ DSS / USS   │
│                  │◄──────────────────────────────── 4. Response ────────────────│             │
└──────────────────┘
```

---

## 4.2 Obtaining a JWT Token

To obtain a JWT, send an HTTP GET or POST request to the Auth Server token endpoint:

**Endpoint:** `http://api.sandbox.brutm.dcta.mil.br/token`

**Query parameters (or request body):**

| Parameter | Description | Example |
|-----------|-------------|---------|
| `apikey` | Your company's API Key, obtained from the Portal UTM. Can also be sent as an HTTP header. | `abc123...` |
| `scope` | The OAuth2 scope(s) you need for the operation. Space-separated for multiple scopes. | `utm.strategic_coordination utm.constraint_processing` |
| `intended_audience` | The FQDN (domain name only, no path) of the server this token will be sent to. | `api.sandbox.brutm.dcta.mil.br` or `uss-b.yourpartner.com` |

**Example request:**
```http
GET /token?scope=utm.strategic_coordination&intended_audience=api.sandbox.brutm.dcta.mil.br
Authorization: ApiKey abc123yourapikey
```

**Example response:**
```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}
```

---

## 4.3 JWT Token Structure

Every token issued by DECEA's Auth Server is a signed JWT containing the following claims:

| Claim | Description | Example |
|-------|-------------|---------|
| `iss` | The URL of the Auth Server that issued the token. | `http://api.sandbox.brutm.dcta.mil.br/token` |
| `exp` | Token expiration timestamp (Unix epoch). Maximum 1 hour from issuance. | `1751327400` |
| `sub` | Your USS's unique identifier — the `manager` identifier in DSS records. | `"my-company-uss"` |
| `scope` | Granted scopes, space-separated. | `"utm.strategic_coordination utm.constraint_processing"` |
| `jti` | Unique token ID for replay protection (RFC 7519). | `"d3e8f921-..."` |
| `aud` | The FQDN of the intended recipient server. | `"api.sandbox.brutm.dcta.mil.br"` |

### Token Validity

- Tokens are valid for **up to 1 hour** (inspect the `exp` claim for the exact expiry time).
- **Cache and reuse tokens** until they are near expiry. Requesting a new token on every API call is wasteful and may cause rate limiting.
- A single token can carry **multiple scopes** (space-separated in the `scope` claim), so you can request all the scopes you need for a workflow in one token request.

---

## 4.4 Available Scopes

### UTM API (`utm.yaml`)

| Scope | Purpose |
|-------|---------|
| `utm.strategic_coordination` | Create, update, delete, and query OIRs in the DSS. Notify subscriber USSs. Fetch OIR details from other USSs. **Required for all standard flight operations.** |
| `utm.constraint_processing` | Query constraint references in the DSS and fetch constraint details from DECEA's USS. **Required if your area may have constraints.** |
| `utm.conformance_monitoring_sa` | Query OIRs and fetch telemetry for off-nominal situations. Used by DECEA's monitoring systems. |
| `utm.constraint_management` | Create, update, and delete constraints. **DECEA only.** |
| `utm.availability_arbitration` | Set USS availability state in the DSS. **Not required in Phase 1.** |
| `utm.aviation_authority` | Access flight authorization details. **DECEA only.** |

### Remote ID API (`remoteid.yaml`)

| Scope | Purpose |
|-------|---------|
| `rid.service_provider` | Create, update, and delete ISAs in the Remote ID DSS. **Required when activating/deactivating flights.** |
| `rid.display_provider` | Query ISAs and telemetry from other USSs. **Required for situational awareness.** |

### Automated Testing APIs

| Scope | Purpose |
|-------|---------|
| `interuss.flight_planning.direct_automated_test` | Used by DECEA's test framework when calling your `flights.yaml` endpoints during homologation. |
| `interuss.flight_planning.plan` | Used by DECEA's test framework to simulate user flight plan actions. |
| `rid.inject_test_data` | Used by DECEA's test framework when calling your `injection.yaml` endpoints during homologation. |
| `interuss.versioning.read_system_versions` | Used by DECEA's test framework when calling your `versioning.yaml` endpoint. |

### Day-to-Day Scope Requirements

For normal production operations, your USS will primarily need:

```
utm.strategic_coordination
utm.constraint_processing
rid.service_provider
rid.display_provider
```

---

## 4.5 The `intended_audience` Parameter — Peer-to-Peer Calls

The `intended_audience` parameter (which becomes the `aud` claim in the JWT) is **critical for peer-to-peer security**. It binds a token to a specific recipient, preventing token replay attacks.

**Rules:**
- When calling **DECEA's DSS** or **Auth Server**: use the domain of the DSS (e.g., `api.sandbox.brutm.dcta.mil.br`).
- When calling **another USS** (e.g., to fetch OIR details): use **only the domain** of that USS's `uss_base_url` — no path, no port (unless non-standard).

**Example:**

If USS B's `uss_base_url` in the DSS is `https://uss-b.partnercompany.com/api/utm`, then when USS A wants to call USS B:

```
intended_audience = "uss-b.partnercompany.com"
```

USS A requests a fresh token with this audience and includes it in the `Authorization` header when calling `GET https://uss-b.partnercompany.com/api/utm/uss/v1/operational_intents/{id}`.

USS B, upon receiving this request, validates that the token's `aud` claim matches its own domain (`uss-b.partnercompany.com`). If it doesn't match, it rejects the request with HTTP 401.

---

## 4.6 Using the Token

Include the token in every outgoing HTTP request:

```http
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
```

This applies to calls to:
- DECEA's DSS (`/dss/v1/...`)
- DECEA's Remote ID DSS (`/dss/identification_service_areas/...`)
- Any peer USS's endpoints (`/uss/v1/...`)

---

## 4.7 Validating Incoming Tokens (Inbound Requests)

Your USS **must validate every inbound request** — whether from DECEA's systems or from other USSs. Failing to do so is a security vulnerability and a homologation failure.

The validation steps are:

### Step 1 — Extract the Token
```
Extract the JWT from the Authorization header:
Authorization: Bearer <token>
```

### Step 2 — Verify the RS256 Signature
Verify the token's digital signature using **DECEA's public RSA key** (obtained from the Portal UTM during onboarding). The signing algorithm is RS256.

If the signature is invalid → reject with **HTTP 401**.

### Step 3 — Verify Token Expiry
Check that the `exp` claim is greater than the current UTC timestamp.

If the token is expired → reject with **HTTP 401**.

### Step 4 — Verify the Audience
Check that the `aud` claim matches **your own server's FQDN**. This prevents a token intended for another USS from being replayed against your server.

If `aud` doesn't match your domain → reject with **HTTP 401**.

### Step 5 — Verify the Scope
Check that the `scope` claim contains the scope required by the specific endpoint being called. Different endpoints require different scopes (see the OpenAPI specifications for each endpoint's required scope).

If the scope is insufficient → reject with **HTTP 403**.

**Go implementation reference** (from the BR-UTM workshop):
```go
func verifyToken(token string, publicKeyFile string) (bool, error) {
    bytes, _ := os.ReadFile(publicKeyFile)
    publicKey, _ := jwt.ParseRSAPublicKeyFromPEM(bytes)
    parts := strings.Split(token, ".")
    err := jwt.SigningMethodRS256.Verify(
        strings.Join(parts[0:2], "."), parts[2], publicKey,
    )
    return err == nil, err
}
```

---

## 4.8 Token Caching Strategy

For optimal performance:

1. **Cache the token** after obtaining it.
2. **Reuse it** for all requests to the same audience with the same scopes, until it's within a safety margin of expiry (e.g., 60 seconds before `exp`).
3. **Request a new token** when the cached one is near expiry or when you need a different scope/audience combination.

You may maintain multiple cached tokens simultaneously — one per `(scope, audience)` combination that your USS needs.

---

## 4.9 Architecture Diagram — Full Authentication Flow

```
                          ┌─────────────────────────────────────────────┐
                          │              DECEA Infrastructure            │
  ┌──────────────┐        │  ┌──────────────┐    ┌────────────────────┐ │
  │              │──────► │  │  Auth Server  │    │        DSS         │ │
  │   Your USS   │ token  │  │  /token       │    │  /dss/v1/...       │ │
  │              │◄─────  │  └──────────────┘    └────────────────────┘ │
  │              │        │                                              │
  │              │─────────────────── Bearer JWT ──────────────────────►│
  │              │◄──────────────────── Response ──────────────────────  │
  └──────┬───────┘        └─────────────────────────────────────────────┘
         │
         │  Peer-to-Peer (with audience-specific token)
         │
         ▼
  ┌──────────────┐
  │  Partner USS │  validates JWT: sig + exp + aud + scope
  │  /uss/v1/... │
  └──────────────┘
```

---

## 4.10 Security Principles

- **Principle of least privilege**: Request only the scopes your operation actually needs. Avoid requesting all scopes in every token.
- **No token sharing**: Tokens are bound to a specific audience (`aud`). A token obtained to talk to the DSS cannot be used to call another USS, and vice versa.
- **Time synchronization**: Your system clock must be synchronized with DECEA's NTP server (`ntp.decea.gov.br`) to ensure token expiry calculations are accurate. See [Chapter 7 — Non-Functional Requirements](./07-non-functional-requirements.md).