Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions docs/Configuration/yaml-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ controls:
android_settings:
custom_settings:
- path: ../lib/android-profile.json
certificates:
- name: wifi-certificate
certificate_authority_name: EST_WIFI
subject_name: /CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID/ST=$FLEET_VAR_HOST_HARDWARE_SERIAL
macos_setup: # Available in Fleet Premium

@marko-lisica marko-lisica Nov 6, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dev note:


Errors:

  • If user specified name that is already taken by another certificate:
    • Couldn't edit "<file_name>" at "<full_path>": "<cert_name>" name is already used by another certificate. Please choose a different name and try again.
  • If the user specified name with characters that are not supported:
    • Couldn't edit "<file_name>" at "<full_path>": Invalid characters in "name" field. Only letters, numbers, spaces, dashes, and underscores allowed.
  • If the user didn't specify the required field:
    • Couldn't edit "<file_name>" at "<full_path>": "<field_name>" is required.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica If user specified invalid Fleet variable, like $FLEET_VAR_BOZO?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica If user specified $FLEET_SECRET_SOMETHING?

@marko-lisica marko-lisica Nov 24, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@getvictor If IdP variable is empty, we should return an error on the host details on the OS settings modal. I think we should be consistent with any invalid variable and secret.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If user specify CA other than custom SCEP proxy, throw an error:

Couldn't edit "<file_name>" at "<full_path>": Currently, only the custom_scep_proxy` certificate authority is supported.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica What about these:

  • If user specified invalid Fleet variable, like $FLEET_VAR_BOZO?
  • If user specified $FLEET_SECRET_SOMETHING?

@marko-lisica marko-lisica Dec 8, 2025

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@getvictor What do we do for configuration profiles in that case? We should do the same.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica configuration profiles support secrets, while the Android certificates do not (we do not have secrets support coded).

configuration profiles return an error on unsupported Fleet variables.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's show this error message if variable is not supported or doesn't exist:

Couldn’t add. Variable "$FLEET_VAR_BOZO" doesn’t exist.

For secrets:

Couldn’t add. Secret variables (prefixed with "$FLEET_SCERET_") are not supported in the certificates.

bootstrap_package: https://example.org/bootstrap_package.pkg
enable_end_user_authentication: true
Expand Down Expand Up @@ -399,15 +403,25 @@ controls:
- `deadline_days` specifies the number of days before Windows installs updates (default: `null`)
- `grace_period_days` specifies the number of days before Windows restarts to install updates (default: `null`)

### macos_settings, windows_settings and android_settings
### macos_settings and windows_settings

- `macos_settings.custom_settings` is a list of paths to macOS, iOS, and iPadOS configuration profiles (.mobileconfig) or declaration profiles (.json).
- `windows_settings.custom_settings` is a list of paths to Windows configuration profiles (.xml).
- `android_settings.custom_settings` is a list of paths to Android configuration profiles (.json).

Use `labels_include_all` to target hosts that have all labels, `labels_include_any` to target hosts that have any label, or `labels_exclude_any` to target hosts that don't have any of the labels. Only one of `labels_include_all`, `labels_include_any`, or `labels_exclude_any` can be specified. If none are specified, all hosts are targeted.

### android_settings

- `android_settings.custom_settings` is a list of paths to Android configuration profiles (.json).

Use `labels_include_all` to target hosts that have all labels, `labels_include_any` to target hosts that have any label, or `labels_exclude_any` to target hosts that don't have any of the labels. Only one of `labels_include_all`, `labels_include_any`, or `labels_exclude_any` can be specified. If none are specified, all hosts are targeted.

#### android_settings.certificates

- `name` is the name of the certificate. Name can be used as a certificate alias to reference in configuration profiles (custom settings).
- `certificate_authority_name` is the name of the [certificate authority (CA)](#certificate-authorities) to issue the certificate from. Currently, only a custom SCEP CA is supported.
- `subject_name` is the certificate's subject name (SN). Separate subject fields by a "/". For example: "/CN=john@example.com/O=Acme Inc.".

#### Variables

For macOS configuration profiles, you can use any of Apple's [built-in variables](https://support.apple.com/en-my/guide/deployment/dep04666af94/1/web/1.0) in [Automated Certificate Management Environment (ACME)](https://developer.apple.com/documentation/devicemanagement/acmecertificate), [Simple Certificate Enrolment Protocol (SCEP)](https://developer.apple.com/documentation/devicemanagement/scep), or [VPN](https://developer.apple.com/documentation/devicemanagement/vpn) payloads.
Expand Down
71 changes: 71 additions & 0 deletions docs/Contributing/reference/api-for-contributors.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ These API endpoints in this document are only used when contributing to Fleet. T
- [Setup](#setup)
- [Scripts](#scripts)
- [Software](#software)
- [Certificates](#certificates)
- [Users](#users)
- [Conditional access](#conditional-access)
- [Host identity](#host-identity)
Expand Down Expand Up @@ -4878,6 +4879,76 @@ Body: <blob>

---

## Certificates

### Apply certificate templates

_Available in Fleet Premium_

`POST /api/latest/fleet/spec/certificates`

#### Parameters

| Name | Type | In | Description |
| --------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| specs | array | body | **Required**. An array of objects with the certificate templates. Each item must contain `name` with the certificate template name, a `team` with a team name, `certificate_authority_id` with the certificate authority id, and `subject_name` with the certificate's subject name. |

> Any existing certificate template that is not included in the list will be removed, and existing templates with the same name as the new template will be edited. Providing an empty list of certificate templates will remove existing scripts.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> Any existing certificate template that is not included in the list will be removed, and existing templates with the same name as the new template will be edited. Providing an empty list of certificate templates will remove existing scripts.
> Any existing certificate template that is not included in the list will be removed, and existing templates with the same name as the new template will be edited. Providing an empty list of certificate templates will remove existing templates.

I think "scripts" might have been a typo? Or are there scripts involved? cc @marko-lisica

(Will approve anyway since this is a contributor endpoint)


#### Example

`POST /api/latest/fleet/spec/certificates`

##### Request body

```json
{
"specs": [
{
"name": "WIFI_CERTIFICATE",
"team": "workstations",
"certificate_authority_id": 1,
"subject_name": "/CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID/ST=$FLEET_VAR_HOST_HARDWARE_SERIAL"
},
{
"name": "WIFI_CERTIFICATE_TEST",
"team": "workstations-canary",
"certificate_authority_id": 1,
"subject_name": "/CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID/ST=$FLEET_VAR_HOST_HARDWARE_SERIAL"
}
]
}
```

##### Default response

`Status: 200`

### Delete certificate templates

`DELETE /api/latest/fleet/spec/certificates`

#### Parameters

| Name | Type | In | Description |
|-----------|---------|-------|----------------------------------------------------------------------------------------|
| ids | array | body | **Required**. An array of certificate template ids to be deleted |
| team_id | integer | body | **Required**. The team_id which the certificate templates you want to delete belong to |

#### Example

`DELETE /api/latest/fleet/spec/certificates`
```json
{
"ids": [1, 2, 3, 4],
"team_id": 1
}
```

##### Default response

`Status: 200`

## Users

### Update user-specific UI settings
Expand Down
115 changes: 115 additions & 0 deletions docs/REST API/rest-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ Returns a list of the activities that have been performed in Fleet. For a compre
- [Update certificate authority (CA)](#update-certificate-authority-ca)
- [List certificate authorities (CAs)](#list-certificate-authorities-cas)
- [Get certificate authority (CA)](#get-certificate-authority-ca)
- [List certificate templates](#list-certificate-templates)
- [Get certificate template](#get-certificate-template)
- [Delete certificate authority (CA)](#delete-certificate-authority-ca)
- [Request certificate](#request-certificate)

Expand Down Expand Up @@ -854,6 +856,119 @@ Get details of the certificate authority.
}
```

### List certificate templates

List certificate added to Fleet. Currently, they can only be added via GitOps.

`GET /api/v1/fleet/certificates`

#### Parameters

| Name | Type | In | Description |
| ----------| ------- | ---- | -------------------------------------------------------------- |
| team | string | query | _Available in Fleet Premium_. The team ID to filter profiles. |
| page | integer | query | Page number of the results to fetch. |
| per_page | integer | query | Results per page. |

#### Request headers

This endpoint accepts the node key from Fleet's Android agent for authentication in addition to [default authentication](#retrieve-your-api-token) with a Bearer token.

The `Authorization` header must be formatted as follows:

```
Authorization: Node key <node_key>
```
Comment on lines +873 to +881

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ksykulev, do we need this? Does the agent call this endpoint? If I remember correctly, we added a new contributor endpoint (/fleetd) for the agent to get cert information?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marko-lisica, the parameter for the team should be team_id instead of team, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndreyKizimenko, that's righ,t it should be team_id, that's consistent with other endpoints. Not sure if this is implemented.

Do we need this? Does the agent call this endpoint? If I remember correctly, we added a new contributor endpoint (/fleetd) for the agent to get cert information?

@ksykulev can you confirm if the agent is using this endpoint and if we support node key authentication for this endpoint?


#### Example

`GET /api/v1/fleet/certificates/`

##### Request headers

```http
Authorization: Node key 24dd9ebf-02cd-4d4c-888a-5caa441ee5d5
```

##### Default response

`Status: 200`

```json
{
"certificates": [
{
"id": 1,
"name": "wifi-certificate",
"certificate_authority_id": "1",
"certificate_authority_name": "PRODUCTION_SCEP_SERVER",
"subject_name": "/CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID/ST=$FLEET_VAR_HOST_HARDWARE_SERIAL",
"created_at": "2025-11-04T00:00:00Z",
},
{
"id": 2,
"name": "vpn-certificate",
"certificate_authority_id": "1",
"certificate_authority_name": "PRODUCTION_SCEP_SERVER",
"subject_name": "/CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID",
"created_at": "2025-11-04T00:00:00Z",
}
],
"meta": {
"has_next_results": false,
"has_previous_results": false
}
}
```

### Get certificate template

Get details of the certificate added to Fleet.

`GET /api/v1/fleet/certificates/:id`

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ksykulev, is this one used by GitOps? Did we end up implementing this one? Now, when we returnsubject_name in the list endpoint, can we remove this one?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ksykulev ping in case you missed this ^


#### Parameters

| Name | Type | In | Description |
|---------------- |-------- |------|-------------------------------------------------------------|
| id | integer | path | **Required**. The ID of the certificate. |
| host_id | integer | query | ID of the host. If included, variables in `subject_name` will be replaced with host's values. |

#### Request headers

This endpoint accepts the node key from Fleet's Android agent for authentication in addition to [default authentication](#retrieve-your-api-token) with a Bearer token.

The `Authorization` header must be formatted as follows:

```
Authorization: Node key <node_key>
```

#### Example

`GET /api/v1/fleet/certificates/1`

##### Request headers

```http
Authorization: Node key 24dd9ebf-02cd-4d4c-888a-5caa441ee5d5
```

##### Default response

`Status: 200`

```json
{
"certificate_authority_id": 2,
"certificate_authority_name": "PRODUCTION_SCEP_SERVER",
"created_at": "2025-11-04T00:00:00Z",
"id": 1,
"name": "wifi-certificate",
"subject_name": "/CN=$FLEET_VAR_HOST_END_USER_IDP_USERNAME/OU=$FLEET_VAR_HOST_UUID/ST=$FLEET_VAR_HOST_HARDWARE_SERIAL",
Comment thread
marko-lisica marked this conversation as resolved.
}
```

### Delete certificate authority (CA)

> **Experimental feature**. This feature is undergoing rapid improvement, which may result in breaking changes to the API or configuration surface. It is not recommended for use in automated workflows.
Expand Down
Loading