Create Application (OIDC Protocol - Worker App)
POST {{apiPath}}/environments/{{envID}}/applications
Worker applications are administrator applications that interact with PingOne platform APIs. The POST {{apiPath}}/environments/{{envID}}/applications operation adds a new application resource to the specified environment. The WORKER type application configuration in this request defines a non-interactive admin app that uses a client credentials grant to provide access to PingOne resources.
When creating a new Worker application, by default the application inherits the same role assignments as the actor that created the application. Best Practice: Disable this inheritance using the assignActorRoles parameter when creating the Worker app. This is for security purposes, to ensure you assign only the minimal set of permissions necessary for the Worker app.
In addition to the required name, protocol, and tokenEndpointAuthMethod properties, and a grantTypes value of CLIENT_CREDENTIALS, the request body also specifies a value of true for the enabled attribute. If a value is not specified for the enabled attribute, it is set to false by default.
Prerequisites
-
Refer to Application Operations for important overview information.
Query parameters
| Parameter | Description |
|---|---|
|
Shows additional information in the |
Request Model
Base application data model (worker application)
Refer to Applications base data model for complete descriptions.
| Property | Required? | Type |
|---|---|---|
|
Optional |
Boolean |
|
Optional |
String |
|
Optional |
String |
|
Optional |
Array |
|
Optional |
UUID |
|
Optional |
String |
|
Required |
Boolean |
|
Optional |
URL |
|
Optional |
URL |
|
Optional |
UUID |
|
Optional |
URL |
|
Required |
String |
|
Required |
String |
|
Optional |
Array |
|
Required |
String |
Additional OIDC settings
Refer to Applications OIDC settings data model for complete descriptions.
If you set the protocol attribute to OPENID_CONNECT, you must provide values for the required OIDC settings. Optional settings can be omitted.
| Property | Required? | Type |
|---|---|---|
|
Optional |
Boolean |
|
String |
Optional |
|
String |
Optional |
|
Optional |
String |
|
Optional |
String |
|
Optional |
String |
|
Required |
URL |
|
Required |
URL |
|
Optional |
Integer |
|
Optional |
Integer |
|
Optional |
Boolean |
|
Required |
String |
|
Optional |
Object |
|
Required |
Object |
|
Required |
String |
|
Optional |
Boolean |
|
Required |
String |
Body
raw ( application/json )
{
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
}
Example Request
-
cURL
-
C#
-
Go
-
HTTP
-
Java
-
jQuery
-
NodeJS
-
Python
-
PHP
-
Ruby
-
Swift
curl --location --globoff '{{apiPath}}/environments/{{envID}}/applications' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{accessToken}}' \
--data '{
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
}'
var options = new RestClientOptions("{{apiPath}}/environments/{{envID}}/applications")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Bearer {{accessToken}}");
var body = @"{" + "\n" +
@" ""enabled"": true," + "\n" +
@" ""name"": ""OIDC-Worker-App_{{$timestamp}}""," + "\n" +
@" ""description"": ""Test Description - CREATE OIDC App (Worker)""," + "\n" +
@" ""type"": ""WORKER""," + "\n" +
@" ""protocol"": ""OPENID_CONNECT""," + "\n" +
@" ""grantTypes"": [" + "\n" +
@" ""CLIENT_CREDENTIALS""" + "\n" +
@" ]," + "\n" +
@" ""assignActorRoles"": false," + "\n" +
@" ""tokenEndpointAuthMethod"": ""CLIENT_SECRET_BASIC""" + "\n" +
@"}";
request.AddStringBody(body, DataFormat.Json);
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "{{apiPath}}/environments/{{envID}}/applications"
method := "POST"
payload := strings.NewReader(`{
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer {{accessToken}}")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
POST /environments/{{envID}}/applications HTTP/1.1
Host: {{apiPath}}
Content-Type: application/json
Authorization: Bearer {{accessToken}}
{
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
}
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"enabled\": true,\n \"name\": \"OIDC-Worker-App_{{$timestamp}}\",\n \"description\": \"Test Description - CREATE OIDC App (Worker)\",\n \"type\": \"WORKER\",\n \"protocol\": \"OPENID_CONNECT\",\n \"grantTypes\": [\n \"CLIENT_CREDENTIALS\"\n ],\n \"assignActorRoles\": false,\n \"tokenEndpointAuthMethod\": \"CLIENT_SECRET_BASIC\"\n}");
Request request = new Request.Builder()
.url("{{apiPath}}/environments/{{envID}}/applications")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer {{accessToken}}")
.build();
Response response = client.newCall(request).execute();
var settings = {
"url": "{{apiPath}}/environments/{{envID}}/applications",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer {{accessToken}}"
},
"data": JSON.stringify({
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require('request');
var options = {
'method': 'POST',
'url': '{{apiPath}}/environments/{{envID}}/applications',
'headers': {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{accessToken}}'
},
body: JSON.stringify({
"enabled": true,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
import requests
import json
url = "{{apiPath}}/environments/{{envID}}/applications"
payload = json.dumps({
"enabled": True,
"name": "OIDC-Worker-App_{{$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": False,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
})
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer {{accessToken}}'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{apiPath}}/environments/{{envID}}/applications');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
'follow_redirects' => TRUE
));
$request->setHeader(array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer {{accessToken}}'
));
$request->setBody('{\n "enabled": true,\n "name": "OIDC-Worker-App_{{$timestamp}}",\n "description": "Test Description - CREATE OIDC App (Worker)",\n "type": "WORKER",\n "protocol": "OPENID_CONNECT",\n "grantTypes": [\n "CLIENT_CREDENTIALS"\n ],\n "assignActorRoles": false,\n "tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"\n}');
try {
$response = $request->send();
if ($response->getStatus() == 200) {
echo $response->getBody();
}
else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
}
catch(HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}
require "uri"
require "json"
require "net/http"
url = URI("{{apiPath}}/environments/{{envID}}/applications")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer {{accessToken}}"
request.body = JSON.dump({
"enabled": true,
"name": "OIDC-Worker-App_{{\$timestamp}}",
"description": "Test Description - CREATE OIDC App (Worker)",
"type": "WORKER",
"protocol": "OPENID_CONNECT",
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"assignActorRoles": false,
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC"
})
response = http.request(request)
puts response.read_body
let parameters = "{\n \"enabled\": true,\n \"name\": \"OIDC-Worker-App_{{$timestamp}}\",\n \"description\": \"Test Description - CREATE OIDC App (Worker)\",\n \"type\": \"WORKER\",\n \"protocol\": \"OPENID_CONNECT\",\n \"grantTypes\": [\n \"CLIENT_CREDENTIALS\"\n ],\n \"assignActorRoles\": false,\n \"tokenEndpointAuthMethod\": \"CLIENT_SECRET_BASIC\"\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "{{apiPath}}/environments/{{envID}}/applications")!,timeoutInterval: Double.infinity)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("Bearer {{accessToken}}", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
}
task.resume()
Example Response
201 Created
{
"_links": {
"self": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/1b22f17b-2e77-465b-b7d2-29eb1005e52b"
},
"environment": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"attributes": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/1b22f17b-2e77-465b-b7d2-29eb1005e52b/attributes"
},
"secret": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/1b22f17b-2e77-465b-b7d2-29eb1005e52b/secret"
},
"grants": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/1b22f17b-2e77-465b-b7d2-29eb1005e52b/grants"
},
"roleAssignments": {
"href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/applications/1b22f17b-2e77-465b-b7d2-29eb1005e52b/roleAssignments"
}
},
"environment": {
"id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
},
"id": "1b22f17b-2e77-465b-b7d2-29eb1005e52b",
"name": "OIDC-Worker-App_1690392436",
"description": "Test Description - CREATE OIDC App (Worker)",
"enabled": true,
"hiddenFromAppPortal": false,
"type": "WORKER",
"accessControl": {
"role": {
"type": "ADMIN_USERS_ONLY"
}
},
"protocol": "OPENID_CONNECT",
"createdAt": "2023-07-26T17:27:16.348Z",
"updatedAt": "2023-07-26T17:27:16.348Z",
"assignActorRoles": false,
"grantTypes": [
"CLIENT_CREDENTIALS"
],
"tokenEndpointAuthMethod": "CLIENT_SECRET_BASIC",
"pkceEnforcement": "OPTIONAL",
"parRequirement": "OPTIONAL",
"devicePollingInterval": 5,
"parTimeout": 60,
"deviceTimeout": 600
}