> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.moveworks.com/llms.txt.
> For full documentation content, see https://docs.moveworks.com/llms-full.txt.

# Verifying Your Build

> Validate that your Content Gateway server conforms to the Moveworks API schema before connecting to Moveworks

## Overview

Before connecting your gateway to Moveworks, use the included `validate.py` script to confirm that every endpoint on your running server returns responses that conform to the Content Gateway API schema.

The validator works against any source system — it tests protocol conformance, not content. Run it against the demo server before writing any code, and again after connecting your real source.

***

## Requirements

* Your gateway server must be running and reachable
* `GATEWAY_API_KEY` set to the key your server expects
* `requests` installed (`pip install -r requirements.txt`)

***

## Running the validator

**Files only** — use this when your Strategy Config is set to Public to all members:

```bash
export GATEWAY_API_KEY=<your-key>
python validate.py
```

**Full validation including users, groups, and permissions** — use this when your Strategy Config is set to ReBAC:

```bash
export GATEWAY_API_KEY=<your-key>
python validate.py --rebac
```

**Against a deployed server:**

```bash
export GATEWAY_API_KEY=<your-key>
SERVER_URL=https://your-gateway.example.com python validate.py --rebac
```

***

## What it checks

**Files only (default)**

| Check                         | What it validates                                                                                                                                    |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Auth — rejects invalid key    | Server returns 401 on a wrong API key                                                                                                                |
| Auth — rejects missing header | Server returns 401 when no Authorization header is sent                                                                                              |
| Auth — accepts valid key      | Server returns 200 with the correct key                                                                                                              |
| `GET /v1/files`               | Response envelope (`value`, `@odata.context`), at least one file returned                                                                            |
| File schema                   | Each file has `id`, `name`, `external_url`, `last_modified_datetime`, `content.mime_type`; HTML files have `body`; binary files have `download_path` |
| `GET /v1/files/{id}`          | Single file returns correct shape and id matches                                                                                                     |

**Additional checks with `--rebac`**

| Check                            | What it validates                                                                              |
| -------------------------------- | ---------------------------------------------------------------------------------------------- |
| `GET /v1/files/{id}/permissions` | Response has `permissions` array; each entry has `id`, `type` (USER or GROUP), `action` (VIEW) |
| `GET /v1/users`                  | Response has `value` array; each user has `id` and `primary_email_addr`                        |
| `GET /v1/groups`                 | Response has `value` array; each group has `id`                                                |
| `GET /v1/groups/{id}/members`    | Each member has `id` and valid `type` (USER or GROUP)                                          |

***

## Example output

```
Moveworks Content Gateway — Schema Validator
════════════════════════════════════════════
  Server:  http://localhost:5001
  Mode:    ReBAC (full)

Authentication
──────────────
  ✓ Rejects invalid API key with 401
  ✓ Rejects missing Authorization header with 401
  ✓ Accepts valid API key

GET /v1/files
─────────────
  ✓ Returns HTTP 200
  ✓ Response has required envelope fields (value, @odata.context)
  ✓ Returns at least one file  (10 files)
  ✓ All files have required fields and valid content shape

GET /v1/files/{id}  (testing id=kb-001)
───────────────────────────────────────
  ✓ Returns HTTP 200
  ✓ File object has required fields
  ✓ Returned file id matches requested id

GET /v1/files/{id}/permissions  (testing id=kb-001)
───────────────────────────────────────────────────
  ✓ Returns HTTP 200
  ✓ Response has permissions array
  ✓ At least one permission entry returned
  ✓ All permission entries have valid shape

GET /v1/users
─────────────
  ✓ Returns HTTP 200
  ✓ Returns at least one user  (5 users)
  ✓ All users have required fields (id, primary_email_addr)

GET /v1/groups
──────────────
  ✓ Returns HTTP 200
  ✓ Returns at least one group  (4 groups)
  ✓ All groups have required id field

GET /v1/groups/{id}/members  (testing id=group-it-staff)
────────────────────────────────────────────────────────
  ✓ Returns HTTP 200  (2 members)
  ✓ All members have valid shape

════════════════════════════════════════════
  ✓ All checks passed
```

***

## If a check fails

The validator prints exactly which field is missing or malformed. The most common causes:

| Symptom                                       | Likely cause                                                                                                    |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `missing fields: primary_email_addr` on users | `map_item_to_user` is returning `email` instead of `primary_email_addr` — check your field mapping in Section 3 |
| `type must be USER or GROUP` on permissions   | `fetch_permissions_for_file` is returning lowercase types — ensure values are uppercased                        |
| Permissions endpoint returns 404              | `fetch_permissions_for_file` not yet implemented — required if using ReBAC strategy                             |
| Auth check fails                              | `GATEWAY_API_KEY` env var doesn't match the key the server was started with                                     |