The Configuration API provides endpoints for managing system configuration options, firmware selection, and working directory management.

# /options/get

**HTTP Method:** GET

**Description:** Retrieves all current configuration values.

**Parameters:** None

**Response Format:**

``` json
{
  "GOLD_MASTER_OS_FILE": "/srv/rpi-sb-provisioner/images/raspios-2025-04-01.img",
  "RPI_SB_WORKDIR": "/srv/rpi-sb-provisioner/work",
  "RPI_SB_PROVISIONER_MANUFACTURING_DB": "/srv/rpi-sb-provisioner/manufacturing.db",
  "RPI_DEVICE_FAMILY": "5",
  "RPI_DEVICE_FIRMWARE_FILE": "/lib/firmware/raspberrypi/bootloader-2712/default/pieeprom-2025-01-17.bin"
}
```

**Notes:**

- Returns all configuration key-value pairs from `/etc/rpi-sb-provisioner/config`

- Configuration values control provisioning behavior

# /options/set

**HTTP Method:** POST

**Description:** Updates one or more configuration values.

**Request Format:**

``` json
{
  "GOLD_MASTER_OS_FILE": "/srv/rpi-sb-provisioner/images/new-image.img",
  "RPI_DEVICE_FAMILY": "5"
}
```

**Response Format:**

HTTP 200 OK with no body on success.

**Error Responses:**

``` json
{
  "error": {
    "status": 500,
    "title": "Config Error",
    "code": "CONFIG_WRITE_ERROR",
    "detail": "Failed to write configuration file"
  }
}
```

**Notes:**

- Merges provided values with existing configuration

- Automatically creates manufacturing database file if path is set and file doesn’t exist

- Clears working directory contents if `RPI_SB_WORKDIR` is modified

# /options/validate

**HTTP Method:** POST

**Description:** Validates a single configuration field value before saving. Performs field-specific validation including file path checks on disk.

**Request Format:**

``` json
{
  "field": "GOLD_MASTER_OS_FILE",
  "value": "/srv/rpi-sb-provisioner/images/raspios-2025-04-01.img"
}
```

**Response Format (Success):**

``` json
{
  "valid": true,
  "field": "GOLD_MASTER_OS_FILE"
}
```

**Response Format (Success with Info):**

``` json
{
  "valid": true,
  "field": "RPI_SB_PROVISIONER_MANUFACTURING_DB",
  "message": "File will be created on save"
}
```

**Response Format (Validation Failure):**

``` json
{
  "valid": false,
  "field": "GOLD_MASTER_OS_FILE",
  "error": "Image file does not exist at specified path"
}
```

**Validation Rules:**

File Path Fields (must exist and be readable):

- `CUSTOMER_KEY_FILE_PEM` - RSA private key file

- `GOLD_MASTER_OS_FILE` - Must have .img extension (mandatory)

- `RPI_DEVICE_BOOTLOADER_CONFIG_FILE` - Bootloader configuration file

Directory Path Fields (must exist or be creatable):

- `RPI_SB_WORKDIR` - Working directory for cached assets

- `RPI_DEVICE_RETRIEVE_KEYPAIR` - Directory for storing device keypairs

Database Path Fields:

- `RPI_SB_PROVISIONER_MANUFACTURING_DB` - SQLite database path (mandatory, parent directory must exist)

Enumerated Values:

- `PROVISIONING_STYLE` - Must be `secure-boot`, `fde-only`, or `naked`

- `RPI_DEVICE_FAMILY` - Must be `4`, `5`, or `2W`

- `RPI_DEVICE_STORAGE_TYPE` - Must be `sd`, `emmc`, or `nvme`

- `RPI_DEVICE_STORAGE_CIPHER` - Must be `aes-xts-plain64` or `xchacha12,aes-adiantum-plain64`

Format-Specific:

- `CUSTOMER_KEY_PKCS11_NAME` - Must start with `pkcs11:` and include `object=` and `type=private` parameters

**Security Measures:**

- **HTTP Method Restriction:** Only accepts POST requests; returns 405 Method Not Allowed for other methods

- **Dynamic Field Whitelist:** Only validates fields that exist in the configuration file; rejects unknown fields

- **Path Canonicalization:** File paths are canonicalized to prevent path traversal attacks (../)

- **Path Validation:** Rejects paths with suspicious patterns after normalization

- **Audit Logging:** All validation requests are logged with client IP addresses

- **Input Validation:** JSON body is validated before processing

- **No Execution:** Endpoint only reads from filesystem, never writes or executes

**Notes:**

- Used by the web UI for real-time field validation

- Always returns HTTP 200 with JSON indicating validation success/failure

- File system checks verify actual file/directory existence and permissions

- Does not modify configuration - use `/options/set` to save values

- Failed validation attempts for unknown fields are logged as security warnings

# /options/clear-workdir

**HTTP Method:** POST

**Description:** Clears all contents of the working directory specified in `RPI_SB_WORKDIR` configuration.

**Parameters:** None

**Response Format:**

HTTP 200 OK with no body on success.

**Notes:**

- Useful when switching OS images or resetting provisioning state

- Does not delete the working directory itself, only its contents

- Safe to call even if directory doesn’t exist

# Firmware Management

## /options/firmware

**HTTP Method:** GET

**Description:** Lists available firmware versions for the configured device family.

**Parameters:** None

**Response Format:**

Returns HTML view with firmware list, release notes, and selection interface.

**Notes:**

- Scans `/lib/firmware/raspberrypi/bootloader-{chip}/` for available firmware

- Automatically groups firmware by version across release channels

- Shows firmware from default, latest, beta, stable, and critical channels

## /options/firmware/set

**HTTP Method:** POST

**Description:** Sets the selected firmware file for device provisioning.

**Request Format:**

``` json
{
  "firmware_path": "/lib/firmware/raspberrypi/bootloader-2712/default/pieeprom-2025-01-17.bin"
}
```

**Response Format:**

HTTP 200 OK with no body on success.

**Error Responses:**

``` json
{
  "error": {
    "status": 400,
    "title": "Invalid Request",
    "code": "FIRMWARE_NOT_FOUND",
    "detail": "Selected firmware file does not exist"
  }
}
```

## /options/firmware/notes/{version}

**HTTP Method:** GET

**Description:** Retrieves release notes for a specific firmware version.

**Path Parameters:**

| Parameter | Type   | Required | Description                           |
|-----------|--------|----------|---------------------------------------|
| version   | String | Yes      | Firmware version in YYYY-MM-DD format |

**Response Format:**

``` json
{
  "version": "2025-01-17",
  "notes": "## 2025-01-17: Description\n\n* Feature 1\n* Bug fix 2\n"
}
```

**Error Responses:**

``` json
{
  "error": "No release notes found for version 2025-01-17"
}
```
