Endurance

OpenID Connect

Configuration

Get the OIDC configuration and group mappings

GET /oidc/config

curl
curl -X GET "https://appliance.example.com/api/v1/oidc/config" \
  -H "Authorization: Bearer $TOKEN"
PHP
<?php

$url = 'https://appliance.example.com/api/v1/oidc/config';
$headers = [
    'Authorization: Bearer ' . $token,
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Python
import requests

headers = {"Authorization": f"Bearer {token}"}

response = requests.get("https://appliance.example.com/api/v1/oidc/config", headers=headers)
response.raise_for_status()
print(response.json())
JavaScript
const response = await fetch('https://appliance.example.com/api/v1/oidc/config', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

const data = await response.json();
Bruno
meta {
  name: Get the OIDC settings
  type: http
  seq: 1
}

get {
  url: https://{{node-0}}:{{port}}/api/v1/oidc/config
  body: none
  auth: bearer
}

auth:bearer {
  token: {{token}}
}
Response
{
  "status": "success",
  "message": "OIDC configuration",
  "data": []
}

Replace the OIDC configuration and group mappings. The body is the whole section: a field it omits is stored at that field’s default rather than left as it was, so send the configuration back in full. The provider fields are required whether or not enabled is set, which is why DELETE is the only way back to an empty section. endpointEnabled is a different kind of flag — it switches a real listener on — so fipId, port and certId are checked only when it is set.

PUT /oidc/config

This change is staged. Send PUT /services/apply to apply it.

Body parameters
enabled boolean

Whether OIDC is offered as a login type.

issuer string Required

The identity provider’s issuer, matched against the id_token iss claim. https only.

clientId string Required
clientSecret string

Required until one is stored: never read back, and an empty string or the mask keeps the stored secret, so only DELETE removes it.

scopes string

Space-separated scopes requested at the authorization endpoint.

redirectUri string Required

The callback URI registered at the identity provider, sent verbatim in the authorize request and the token exchange. https only.

authorizationEndpoint string Required

https only.

tokenEndpoint string Required

https only.

userinfoEndpoint string

Optional claims fallback. https only when set.

jwksUri string Required

Where the id_token signature is verified against. https only.

groupsClaim string

The id_token claim the group membership is read from.

emailClaim string
firstNameClaim string
lastNameClaim string
fallbackGroupId string

Appliance group id assigned when no mapping matches. Empty for none.

mappings array of object

Claim value to appliance group rules. Replaced wholesale.

Fields
claimValue string

A value of groupsClaim to match on.

groupIds array of string

Appliance group ids granted to a user carrying that value.

endpointEnabled boolean

Whether the dedicated FIP-bound OIDC login endpoint is served.

fipId string

Floating IP the OIDC endpoint binds. Required when endpointEnabled.

port integer

Port the OIDC endpoint listens on. Must be free of any other service.

certId string

Certificate presented on the OIDC endpoint, which the browser must trust. Required when endpointEnabled.

curl
curl -X PUT "https://appliance.example.com/api/v1/oidc/config" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "enabled": true,
  "issuer": "<issuer>",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "scopes": "<scopes>",
  "redirectUri": "<redirectUri>",
  "authorizationEndpoint": "<authorizationEndpoint>",
  "tokenEndpoint": "<tokenEndpoint>",
  "userinfoEndpoint": "<userinfoEndpoint>",
  "jwksUri": "<jwksUri>",
  "groupsClaim": "<groupsClaim>",
  "emailClaim": "<emailClaim>",
  "firstNameClaim": "<firstNameClaim>",
  "lastNameClaim": "<lastNameClaim>",
  "fallbackGroupId": "<fallbackGroupId>",
  "mappings": [
    {
      "claimValue": "<claimValue>",
      "groupIds": [
        "<groupIds>"
      ]
    }
  ],
  "endpointEnabled": true,
  "fipId": "<fipId>",
  "port": 0,
  "certId": "<certId>"
}'
PHP
<?php

$url = 'https://appliance.example.com/api/v1/oidc/config';
$headers = [
    'Authorization: Bearer ' . $token,
    'Content-Type: application/json',
];

$payload = [
    'enabled' => true,
    'issuer' => '<issuer>',
    'clientId' => '<clientId>',
    'clientSecret' => '<clientSecret>',
    'scopes' => '<scopes>',
    'redirectUri' => '<redirectUri>',
    'authorizationEndpoint' => '<authorizationEndpoint>',
    'tokenEndpoint' => '<tokenEndpoint>',
    'userinfoEndpoint' => '<userinfoEndpoint>',
    'jwksUri' => '<jwksUri>',
    'groupsClaim' => '<groupsClaim>',
    'emailClaim' => '<emailClaim>',
    'firstNameClaim' => '<firstNameClaim>',
    'lastNameClaim' => '<lastNameClaim>',
    'fallbackGroupId' => '<fallbackGroupId>',
    'mappings' => [
        [
            'claimValue' => '<claimValue>',
            'groupIds' => [
                '<groupIds>',
            ],
        ],
    ],
    'endpointEnabled' => true,
    'fipId' => '<fipId>',
    'port' => 0,
    'certId' => '<certId>',
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POSTFIELDS => json_encode($payload),
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Python
import requests

headers = {"Authorization": f"Bearer {token}"}
payload = {
    "enabled": true,
    "issuer": "<issuer>",
    "clientId": "<clientId>",
    "clientSecret": "<clientSecret>",
    "scopes": "<scopes>",
    "redirectUri": "<redirectUri>",
    "authorizationEndpoint": "<authorizationEndpoint>",
    "tokenEndpoint": "<tokenEndpoint>",
    "userinfoEndpoint": "<userinfoEndpoint>",
    "jwksUri": "<jwksUri>",
    "groupsClaim": "<groupsClaim>",
    "emailClaim": "<emailClaim>",
    "firstNameClaim": "<firstNameClaim>",
    "lastNameClaim": "<lastNameClaim>",
    "fallbackGroupId": "<fallbackGroupId>",
    "mappings": [
        {
            "claimValue": "<claimValue>",
            "groupIds": [
                "<groupIds>"
            ]
        }
    ],
    "endpointEnabled": true,
    "fipId": "<fipId>",
    "port": 0,
    "certId": "<certId>"
}

response = requests.put("https://appliance.example.com/api/v1/oidc/config", headers=headers, json=payload)
response.raise_for_status()
print(response.json())
JavaScript
const response = await fetch('https://appliance.example.com/api/v1/oidc/config', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "enabled": true,
  "issuer": "<issuer>",
  "clientId": "<clientId>",
  "clientSecret": "<clientSecret>",
  "scopes": "<scopes>",
  "redirectUri": "<redirectUri>",
  "authorizationEndpoint": "<authorizationEndpoint>",
  "tokenEndpoint": "<tokenEndpoint>",
  "userinfoEndpoint": "<userinfoEndpoint>",
  "jwksUri": "<jwksUri>",
  "groupsClaim": "<groupsClaim>",
  "emailClaim": "<emailClaim>",
  "firstNameClaim": "<firstNameClaim>",
  "lastNameClaim": "<lastNameClaim>",
  "fallbackGroupId": "<fallbackGroupId>",
  "mappings": [
    {
      "claimValue": "<claimValue>",
      "groupIds": [
        "<groupIds>"
      ]
    }
  ],
  "endpointEnabled": true,
  "fipId": "<fipId>",
  "port": 0,
  "certId": "<certId>"
}),
});

const data = await response.json();
Bruno
meta {
  name: Update the OIDC settings
  type: http
  seq: 1
}

put {
  url: https://{{node-0}}:{{port}}/api/v1/oidc/config
  body: json
  auth: bearer
}

headers {
  Content-Type: application/json
}

auth:bearer {
  token: {{token}}
}

body:json {
  {
    "enabled": true,
    "issuer": "<issuer>",
    "clientId": "<clientId>",
    "clientSecret": "<clientSecret>",
    "scopes": "<scopes>",
    "redirectUri": "<redirectUri>",
    "authorizationEndpoint": "<authorizationEndpoint>",
    "tokenEndpoint": "<tokenEndpoint>",
    "userinfoEndpoint": "<userinfoEndpoint>",
    "jwksUri": "<jwksUri>",
    "groupsClaim": "<groupsClaim>",
    "emailClaim": "<emailClaim>",
    "firstNameClaim": "<firstNameClaim>",
    "lastNameClaim": "<lastNameClaim>",
    "fallbackGroupId": "<fallbackGroupId>",
    "mappings": [
      {
        "claimValue": "<claimValue>",
        "groupIds": [
          "<groupIds>"
        ]
      }
    ],
    "endpointEnabled": true,
    "fipId": "<fipId>",
    "port": 0,
    "certId": "<certId>"
  }
}
Response
{
  "status": "success",
  "message": "OIDC configuration updated",
  "data": []
}

Return the OIDC configuration to its shipped state: disabled, with no provider details and no client secret. The provider fields are enforced on an update whether or not OIDC is enabled, so this is the only way to empty the section. This also disables the dedicated OIDC endpoint, which stops when the pending changes are applied. The provisioned OIDC users are not affected.

DELETE /oidc/config

This change is staged. Send PUT /services/apply to apply it.

curl
curl -X DELETE "https://appliance.example.com/api/v1/oidc/config" \
  -H "Authorization: Bearer $TOKEN"
PHP
<?php

$url = 'https://appliance.example.com/api/v1/oidc/config';
$headers = [
    'Authorization: Bearer ' . $token,
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Python
import requests

headers = {"Authorization": f"Bearer {token}"}

response = requests.delete("https://appliance.example.com/api/v1/oidc/config", headers=headers)
response.raise_for_status()
print(response.json())
JavaScript
const response = await fetch('https://appliance.example.com/api/v1/oidc/config', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

const data = await response.json();
Bruno
meta {
  name: Clear the OIDC settings
  type: http
  seq: 1
}

delete {
  url: https://{{node-0}}:{{port}}/api/v1/oidc/config
  body: none
  auth: bearer
}

auth:bearer {
  token: {{token}}
}
Response
{
  "status": "success",
  "message": "OIDC configuration cleared",
  "data": []
}

Ingest an OIDC discovery document

Fetch and parse the identity provider’s discovery document

POST /oidc/config/discovery

This change is staged. Send PUT /services/apply to apply it.

curl
curl -X POST "https://appliance.example.com/api/v1/oidc/config/discovery" \
  -H "Authorization: Bearer $TOKEN"
PHP
<?php

$url = 'https://appliance.example.com/api/v1/oidc/config/discovery';
$headers = [
    'Authorization: Bearer ' . $token,
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_RETURNTRANSFER => true,
]);

$response = json_decode(curl_exec($ch), true);
curl_close($ch);
Python
import requests

headers = {"Authorization": f"Bearer {token}"}

response = requests.post("https://appliance.example.com/api/v1/oidc/config/discovery", headers=headers)
response.raise_for_status()
print(response.json())
JavaScript
const response = await fetch('https://appliance.example.com/api/v1/oidc/config/discovery', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
  },
});

const data = await response.json();
Bruno
meta {
  name: Ingest an OIDC discovery document
  type: http
  seq: 1
}

post {
  url: https://{{node-0}}:{{port}}/api/v1/oidc/config/discovery
  body: none
  auth: bearer
}

auth:bearer {
  token: {{token}}
}
Response
{
  "status": "success",
  "message": "Identity-provider discovery document parsed",
  "data": []
}