PingOne Platform APIs

Create Rule

 

POST {{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules

The POST {{apiPath}}/environments/{{envID}}/propagation/rules operation adds a new propagation rule resource to the specified environment resource.

The property populationExpression is a SCIM filter applied to any user attribute of the source identity store. Supported operators include sw (starts with), ew (ends with), co (contains), and eq (equals). Refer to SCIM operators for a full list of operators and supported attributes.

For example, you can define a SCIM filter for a Workday inbound rule as: "populationExpression": "supervisoryOrg eq \"Human Resources\"" and the rule will synchronize all users from Workday that have a supervisoryOrg of Human Resources.

Available user attributes for any store can be obtained with the appropriate request found in Propagation Store Metadata and looking under userAttributes.

Prerequisites

Request Model

Refer to Propagation rule data model for full property descriptions.

Property Type Required?

active

Boolean

Optional

configuration

Object

Required/Optional

deprovision (deprecated)

Boolean

Optional

description

String

Optional

groups

Object[]

Optional

groups.id

String

Required

name

String

Required

plan.id

String

Required

populationExpression

String

Optional

populations.id (deprecated)

String[]

Optional

sourceStore.id

String

Required

targetStore.id

String

Required

The configuration object is required for outbound LDAP Gateway stores (type LdapGateway) and inbound LDAP Gateway stores (where users are provisioned into PingOne), optional for all others and ignored if used.

This outbound LDAP configuration object is required for outbound LDAP Gateway stores (type LdapGateway).

Property Type Required?

BASE_DN

String

Required

RDN_ATTRIBUTE

String

Required

This inbound LDAP configuration object is required for inbound LDAP Gateway stores (where users are provisioned into PingOne).

If AUTHENTICATE_VIA_AD_LDAP is false, then the GATEWAY_USER_TYPE_* configuration attributes are optional and ignored if used. Note that USERS_BASE_DN is always required and unaffected by the value of AUTHENTICATE_VIA_AD_LDAP.

AUTHENTICATE_VIA_AD_LDAP can only be true if a userTypes object is configured in the gateway as returned by Read One Gateway. The remaining configuration attributes are required and must exactly match the corresponding attribute in the userTypes array object.

The userTypes object must not have a newUserLookup property if it is to be used with AUTHENTICATE_VIA_AD_LDAP as true.
Property Type Required?

AUTHENTICATE_VIA_AD_LDAP

Boolean

Required

GATEWAY_USER_TYPE_ALLOW_PASSWORD_CHANGES

Boolean

Required/Optional

GATEWAY_USER_TYPE_CORRELATION_ATTRIBUTES

String

Required/Optional

GATEWAY_USER_TYPE_ID

String

Required/Optional

GATEWAY_USER_TYPE_NAME

String

Required/Optional

GATEWAY_USER_TYPE_PASSWORD_AUTHORITY

String

Required/Optional

USERS_BASE_DN

String

Required

Headers

Authorization      Bearer {{accessToken}}

Content-Type      application/json

Body

raw ( application/json )

{
    "plan": {
        "id": "{{planID}}"
    },
    "environment": {
        "id": "{{envID}}"
    },
    "sourceStore": {
        "id": "{{sourceStoreID}}"
    },
    "targetStore": {
        "id": "{{targetStoreID}}"
    },
    "groups": [
         {
             "id": "{{groupID}}"
         }
     ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
}

Example Request

  • cURL

  • C#

  • Go

  • HTTP

  • Java

  • jQuery

  • NodeJS

  • Python

  • PHP

  • Ruby

  • Swift

curl --location --globoff '{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {{accessToken}}' \
--data '{
    "plan": {
        "id": "{{planID}}"
    },
    "environment": {
        "id": "{{envID}}"
    },
    "sourceStore": {
        "id": "{{sourceStoreID}}"
    },
    "targetStore": {
        "id": "{{targetStoreID}}"
    },
    "groups": [
         {
             "id": "{{groupID}}"
         }
     ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
}'
var options = new RestClientOptions("{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules")
{
  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" +
@"    ""plan"": {" + "\n" +
@"        ""id"": ""{{planID}}""" + "\n" +
@"    }," + "\n" +
@"    ""environment"": {" + "\n" +
@"        ""id"": ""{{envID}}""" + "\n" +
@"    }," + "\n" +
@"    ""sourceStore"": {" + "\n" +
@"        ""id"": ""{{sourceStoreID}}""" + "\n" +
@"    }," + "\n" +
@"    ""targetStore"": {" + "\n" +
@"        ""id"": ""{{targetStoreID}}""" + "\n" +
@"    }," + "\n" +
@"    ""groups"": [" + "\n" +
@"         {" + "\n" +
@"             ""id"": ""{{groupID}}""" + "\n" +
@"         }" + "\n" +
@"     ]," + "\n" +
@"    ""deprovision"": true," + "\n" +
@"    ""name"": ""rule name""," + "\n" +
@"    ""description"": ""rule description""," + "\n" +
@"    ""populationExpression"": ""population.id eq \""{{popID}}\""""" + "\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}}/propagation/plans/{{planID}}/rules"
  method := "POST"

  payload := strings.NewReader(`{
    "plan": {
        "id": "{{planID}}"
    },
    "environment": {
        "id": "{{envID}}"
    },
    "sourceStore": {
        "id": "{{sourceStoreID}}"
    },
    "targetStore": {
        "id": "{{targetStoreID}}"
    },
    "groups": [
         {
             "id": "{{groupID}}"
         }
     ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
}`)

  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}}/propagation/plans/{{planID}}/rules HTTP/1.1
Host: {{apiPath}}
Content-Type: application/json
Authorization: Bearer {{accessToken}}

{
    "plan": {
        "id": "{{planID}}"
    },
    "environment": {
        "id": "{{envID}}"
    },
    "sourceStore": {
        "id": "{{sourceStoreID}}"
    },
    "targetStore": {
        "id": "{{targetStoreID}}"
    },
    "groups": [
         {
             "id": "{{groupID}}"
         }
     ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
}
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"plan\": {\n        \"id\": \"{{planID}}\"\n    },\n    \"environment\": {\n        \"id\": \"{{envID}}\"\n    },\n    \"sourceStore\": {\n        \"id\": \"{{sourceStoreID}}\"\n    },\n    \"targetStore\": {\n        \"id\": \"{{targetStoreID}}\"\n    },\n    \"groups\": [\n         {\n             \"id\": \"{{groupID}}\"\n         }\n     ],\n    \"deprovision\": true,\n    \"name\": \"rule name\",\n    \"description\": \"rule description\",\n    \"populationExpression\": \"population.id eq \\\"{{popID}}\\\"\"\n}");
Request request = new Request.Builder()
  .url("{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules")
  .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}}/propagation/plans/{{planID}}/rules",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer {{accessToken}}"
  },
  "data": JSON.stringify({
    "plan": {
      "id": "{{planID}}"
    },
    "environment": {
      "id": "{{envID}}"
    },
    "sourceStore": {
      "id": "{{sourceStoreID}}"
    },
    "targetStore": {
      "id": "{{targetStoreID}}"
    },
    "groups": [
      {
        "id": "{{groupID}}"
      }
    ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
  }),
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules',
  'headers': {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer {{accessToken}}'
  },
  body: JSON.stringify({
    "plan": {
      "id": "{{planID}}"
    },
    "environment": {
      "id": "{{envID}}"
    },
    "sourceStore": {
      "id": "{{sourceStoreID}}"
    },
    "targetStore": {
      "id": "{{targetStoreID}}"
    },
    "groups": [
      {
        "id": "{{groupID}}"
      }
    ],
    "deprovision": true,
    "name": "rule name",
    "description": "rule description",
    "populationExpression": "population.id eq \"{{popID}}\""
  })

};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests
import json

url = "{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules"

payload = json.dumps({
  "plan": {
    "id": "{{planID}}"
  },
  "environment": {
    "id": "{{envID}}"
  },
  "sourceStore": {
    "id": "{{sourceStoreID}}"
  },
  "targetStore": {
    "id": "{{targetStoreID}}"
  },
  "groups": [
    {
      "id": "{{groupID}}"
    }
  ],
  "deprovision": True,
  "name": "rule name",
  "description": "rule description",
  "populationExpression": "population.id eq \"{{popID}}\""
})
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}}/propagation/plans/{{planID}}/rules');
$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    "plan": {\n        "id": "{{planID}}"\n    },\n    "environment": {\n        "id": "{{envID}}"\n    },\n    "sourceStore": {\n        "id": "{{sourceStoreID}}"\n    },\n    "targetStore": {\n        "id": "{{targetStoreID}}"\n    },\n    "groups": [\n         {\n             "id": "{{groupID}}"\n         }\n     ],\n    "deprovision": true,\n    "name": "rule name",\n    "description": "rule description",\n    "populationExpression": "population.id eq \\"{{popID}}\\""\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}}/propagation/plans/{{planID}}/rules")

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({
  "plan": {
    "id": "{{planID}}"
  },
  "environment": {
    "id": "{{envID}}"
  },
  "sourceStore": {
    "id": "{{sourceStoreID}}"
  },
  "targetStore": {
    "id": "{{targetStoreID}}"
  },
  "groups": [
    {
      "id": "{{groupID}}"
    }
  ],
  "deprovision": true,
  "name": "rule name",
  "description": "rule description",
  "populationExpression": "population.id eq \"{{popID}}\""
})

response = http.request(request)
puts response.read_body
let parameters = "{\n    \"plan\": {\n        \"id\": \"{{planID}}\"\n    },\n    \"environment\": {\n        \"id\": \"{{envID}}\"\n    },\n    \"sourceStore\": {\n        \"id\": \"{{sourceStoreID}}\"\n    },\n    \"targetStore\": {\n        \"id\": \"{{targetStoreID}}\"\n    },\n    \"groups\": [\n         {\n             \"id\": \"{{groupID}}\"\n         }\n     ],\n    \"deprovision\": true,\n    \"name\": \"rule name\",\n    \"description\": \"rule description\",\n    \"populationExpression\": \"population.id eq \\\"{{popID}}\\\"\"\n}"
let postData = parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{apiPath}}/environments/{{envID}}/propagation/plans/{{planID}}/rules")!,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

{
    "id": "66cc421f-8b1e-4b82-8f0b-20a1b7eec998",
    "environment": {
        "id": "abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6"
    },
    "createdAt": "2023-05-22T18:08:32.784Z",
    "updatedAt": "2023-05-22T18:08:32.784Z",
    "plan": {
        "id": "9b0f46a7-1987-4c80-8dfd-b4f34a96d216"
    },
    "sourceStore": {
        "id": "01f31fb7-6e39-4678-9420-e3b2e7358fdd"
    },
    "targetStore": {
        "id": "d43ab23a-0c41-46b7-9468-66b52561636e"
    },
    "name": "rule name",
    "description": "rule description",
    "active": false,
    "populationExpression": "population.id eq \"cb3ef0a0-0ff5-4f60-ae82-4ae65d9d0e3a\"",
    "deprovision": true,
    "groups": [
        {
            "id": "1da23f50-4258-43e4-93cd-a7e9e9c5e167"
        }
    ],
    "_links": {
        "create": {
            "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/plans/9b0f46a7-1987-4c80-8dfd-b4f34a96d216/rules"
        },
        "self": {
            "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/rules/66cc421f-8b1e-4b82-8f0b-20a1b7eec998"
        },
        "update": {
            "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/rules/66cc421f-8b1e-4b82-8f0b-20a1b7eec998"
        },
        "delete": {
            "href": "https://api.pingone.com/v1/environments/abfba8f6-49eb-49f5-a5d9-80ad5c98f9f6/propagation/rules/66cc421f-8b1e-4b82-8f0b-20a1b7eec998"
        }
    }
}