mirror of
https://github.com/LukeHagar/developer.sailpoint.com.git
synced 2025-12-07 20:37:46 +00:00
Prettified Code!
This commit is contained in:
committed by
GitHub Action
parent
f5b6aaf14f
commit
2cd5ccfc81
146
CONTRIBUTING.md
146
CONTRIBUTING.md
@@ -1,148 +1,124 @@
|
|||||||
# Contribute to developer.sailpoint.com
|
# Contribute to developer.sailpoint.com
|
||||||
|
|
||||||
The SailPoint Developer Relations Team is always actively working to improve https://developer.sailpoint.com to make the site as useful as possible to the SailPoint Developer Community.
|
The SailPoint Developer Relations Team is always actively working to improve https://developer.sailpoint.com to make the site as useful as possible to the SailPoint Developer Community. This means adding and maintaining new resources for the community, like new tools and educational content, along with accurate, complete, and current guides and information. The most valuable resource of all, however, is the community itself! We greatly appreciate any input, feedback, and direct contributions you can provide to the community, big or small. And we want to make the process of contributing to this project as easy and transparent as possible.
|
||||||
This means adding and maintaining new resources for the community, like new tools and educational content, along with accurate, complete, and current guides and information.
|
|
||||||
The most valuable resource of all, however, is the community itself!
|
|
||||||
We greatly appreciate any input, feedback, and direct contributions you can provide to the community, big or small.
|
|
||||||
And we want to make the process of contributing to this project as easy and transparent as possible.
|
|
||||||
|
|
||||||
This document will detail the different ways that you can contribute to the community.
|
This document will detail the different ways that you can contribute to the community.
|
||||||
|
|
||||||
|
These are the main ways that you can contribute:
|
||||||
|
|
||||||
These are the main ways that you can contribute:
|
|
||||||
- [Report issues](#report-issues)
|
- [Report issues](#report-issues)
|
||||||
- [Request new features](#request-new-features)
|
- [Request new features](#request-new-features)
|
||||||
- [Submit a fix](#submit-a-fix)
|
- [Submit a fix](#submit-a-fix)
|
||||||
- [Submit a new feature](#submit-a-new-feature)
|
- [Submit a new feature](#submit-a-new-feature)
|
||||||
|
|
||||||
## How we use GitHub
|
## How we use GitHub
|
||||||
|
|
||||||
We use GitHub to host code, track issues and feature requests, and manage contributions with pull requests.
|
We use GitHub to host code, track issues and feature requests, and manage contributions with pull requests.
|
||||||
|
|
||||||
This project is open source, which means that it's publicly accessible, allowing anyone who comes across it to view, share, and improve its source code.
|
This project is open source, which means that it's publicly accessible, allowing anyone who comes across it to view, share, and improve its source code.
|
||||||
|
|
||||||
## GitHub flow and pull requests
|
## GitHub flow and pull requests
|
||||||
|
|
||||||
The best way to propose changes to the codebase is to use pull requests, and [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow) is our preferred method of accepting pull requests.
|
The best way to propose changes to the codebase is to use pull requests, and [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow) is our preferred method of accepting pull requests.
|
||||||
|
|
||||||
This is the basic GitHub flow we use for direct contributions to the codebase:
|
This is the basic GitHub flow we use for direct contributions to the codebase:
|
||||||
|
|
||||||
1. Fork the repository and create your own branch from `main`.
|
1. Fork the repository and create your own branch from `main`.
|
||||||
2. Make your changes in your `main` branch.
|
2. Make your changes in your `main` branch.
|
||||||
3. Push the changes to the repository's `main` branch.
|
3. Push the changes to the repository's `main` branch.
|
||||||
4. Create your pull request!
|
4. Create your pull request!
|
||||||
5. SailPoint Developer Relations team members will review your pull request and merge it in!
|
5. SailPoint Developer Relations team members will review your pull request and merge it in!
|
||||||
|
|
||||||
## GitHub Issues
|
## GitHub Issues
|
||||||
|
|
||||||
We use [GitHub Issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) to publicly track bugs and feature requests.
|
We use [GitHub Issues](https://docs.github.com/en/issues/tracking-your-work-with-issues/about-issues) to publicly track bugs and feature requests.
|
||||||
|
|
||||||
## Report issues
|
## Report issues
|
||||||
|
|
||||||
You may encounter bugs and incorrect or outdated information when you explore the site.
|
You may encounter bugs and incorrect or outdated information when you explore the site. We appreciate your help in identifying bugs of all sizes, from broken links or typos to major issues preventing you from using a resource.
|
||||||
We appreciate your help in identifying bugs of all sizes, from broken links or typos to major issues preventing you from using a resource.
|
|
||||||
|
|
||||||
We use GitHub issues to track bugs publicly. If you see an issue with the site, please [report it here](https://github.com/sailpoint-oss/developer.sailpoint.com/issues/new?assignees=&labels=&template=bug-report.md&title=%5BBug%5D+Your+Bug+Report+Here).
|
We use GitHub issues to track bugs publicly. If you see an issue with the site, please [report it here](https://github.com/sailpoint-oss/developer.sailpoint.com/issues/new?assignees=&labels=&template=bug-report.md&title=%5BBug%5D+Your+Bug+Report+Here).
|
||||||
|
|
||||||
We love thorough bug reports.
|
We love thorough bug reports. The more details you include, the faster we can troubleshoot and fix the issue. Great bug reports include these details:
|
||||||
The more details you include, the faster we can troubleshoot and fix the issue.
|
|
||||||
Great bug reports include these details:
|
|
||||||
|
|
||||||
1. A summary of the issue
|
1. A summary of the issue
|
||||||
2. The steps we can take to reproduce the issue
|
2. The steps we can take to reproduce the issue
|
||||||
- Be as specific as you can when you describe these steps.
|
- Be as specific as you can when you describe these steps.
|
||||||
- Give us sample code if you can.
|
- Give us sample code if you can.
|
||||||
3. What you expect to happen
|
3. What you expect to happen
|
||||||
4. What actually happens
|
4. What actually happens
|
||||||
5. Screenshots
|
5. Screenshots
|
||||||
6. The operating system you were using when you encountered the issue
|
6. The operating system you were using when you encountered the issue
|
||||||
7. The browser you were using when you encountered the issue
|
7. The browser you were using when you encountered the issue
|
||||||
8. Notes
|
8. Notes
|
||||||
- If you have an idea, tell us why you think the issue may be occurring, or what you think we should do to resolve it.
|
- If you have an idea, tell us why you think the issue may be occurring, or what you think we should do to resolve it.
|
||||||
- Whatever you tried that didn't work.
|
- Whatever you tried that didn't work.
|
||||||
- Anything else you think might be useful to us.
|
- Anything else you think might be useful to us.
|
||||||
|
|
||||||
## Request new features
|
## Request new features
|
||||||
|
|
||||||
Many of our most valuable resources originate in ideas suggested by the community!
|
Many of our most valuable resources originate in ideas suggested by the community! You may have an idea that will improve the site. We would love to hear it and possibly implement it!
|
||||||
You may have an idea that will improve the site.
|
|
||||||
We would love to hear it and possibly implement it!
|
|
||||||
|
|
||||||
We use GitHub issues to track feature requests. Please use [this template](https://github.com/sailpoint-oss/developer.sailpoint.com/issues/new?assignees=&labels=&template=feature-request.md&title=%5BFeature%5D+Your+Feature+Request+Here) when you request a new feature.
|
We use GitHub issues to track feature requests. Please use [this template](https://github.com/sailpoint-oss/developer.sailpoint.com/issues/new?assignees=&labels=&template=feature-request.md&title=%5BFeature%5D+Your+Feature+Request+Here) when you request a new feature.
|
||||||
|
|
||||||
We love thorough feature requests.
|
We love thorough feature requests. The more details you include, the faster we can implement your request. Great feature requests include these details:
|
||||||
The more details you include, the faster we can implement your request.
|
|
||||||
Great feature requests include these details:
|
|
||||||
|
|
||||||
1. Tell us whether this feature is related to a problem.
|
1. Tell us whether this feature is related to a problem.
|
||||||
- If it is, describe the problem.
|
- If it is, describe the problem.
|
||||||
2. Describe your desired solution.
|
2. Describe your desired solution.
|
||||||
3. Describe alternative solutions you may use yourself or other solutions you may have considered.
|
3. Describe alternative solutions you may use yourself or other solutions you may have considered.
|
||||||
4. Notes
|
4. Notes
|
||||||
- If possible, include how you think this solution would benefit others.
|
- If possible, include how you think this solution would benefit others.
|
||||||
- Anything else you think might be useful to us.
|
- Anything else you think might be useful to us.
|
||||||
|
|
||||||
## Submit a fix
|
## Submit a fix
|
||||||
|
|
||||||
One of the main benefits of making our project open source is that it makes it possible for the community to contribute directly.
|
One of the main benefits of making our project open source is that it makes it possible for the community to contribute directly. We will always respond as quickly as we can to any issues you report, but if you know how to fix an issue, the fastest way to get it fixed is to submit a pull request and make the fix yourself! If you can do this, it's tremendously helpful to us in our efforts to improve the community, and, if you're interested, you will receive ambassador points for your fix. Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
||||||
We will always respond as quickly as we can to any issues you report, but if you know how to fix an issue, the fastest way to get it fixed is to submit a pull request and make the fix yourself!
|
|
||||||
If you can do this, it's tremendously helpful to us in our efforts to improve the community, and, if you're interested, you will receive ambassador points for your fix.
|
|
||||||
Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
|
||||||
|
|
||||||
To submit a fix, follow these steps:
|
To submit a fix, follow these steps:
|
||||||
1. Fork the repository and copy the `main` branch.
|
|
||||||
2. Pull the latest code and ensure that it's running properly.
|
|
||||||
3. Create a new branch from main.
|
|
||||||
- Follow this naming convention for your branch: `fix/your-fix-name`
|
|
||||||
4. Create a pull request from your branch to our origin repository's `main` branch!
|
|
||||||
|
|
||||||
Once you create the pull request, the SailPoint Developer Relations Team will be tagged.
|
1. Fork the repository and copy the `main` branch.
|
||||||
Someone will then review the pull request and merge it in!
|
2. Pull the latest code and ensure that it's running properly.
|
||||||
|
3. Create a new branch from main.
|
||||||
|
- Follow this naming convention for your branch: `fix/your-fix-name`
|
||||||
|
4. Create a pull request from your branch to our origin repository's `main` branch!
|
||||||
|
|
||||||
|
Once you create the pull request, the SailPoint Developer Relations Team will be tagged. Someone will then review the pull request and merge it in!
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
You cannot directly make changes to the API specifications. These files are regularly pulled from a private repository and auto-generated.
|
You cannot directly make changes to the API specifications. These files are regularly pulled from a private repository and auto-generated.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Submit a new feature
|
## Submit a new feature
|
||||||
|
|
||||||
We will always respond to your feature requests and implement them as soon as we can.
|
We will always respond to your feature requests and implement them as soon as we can. However, if you have an idea for a new feature and know how to implement it yourself, the fastest way to add the feature is to submit a pull request and add the feature yourself! If you can do this, we greatly appreciate it, and other community members will benefit from your contribution! And if you're interested, you will receive ambassador points for your feature contribution. Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
||||||
However, if you have an idea for a new feature and know how to implement it yourself, the fastest way to add the feature is to submit a pull request and add the feature yourself!
|
|
||||||
If you can do this, we greatly appreciate it, and other community members will benefit from your contribution!
|
|
||||||
And if you're interested, you will receive ambassador points for your feature contribution.
|
|
||||||
Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
|
||||||
|
|
||||||
To submit a new feature, follow these steps:
|
To submit a new feature, follow these steps:
|
||||||
1. Fork the repository and copy the `main` branch.
|
|
||||||
2. Pull the latest code and ensure that it's running properly.
|
|
||||||
3. Create a new branch from main.
|
|
||||||
- Follow this naming convention for your branch: `feature/your-feature-name`
|
|
||||||
4. Create a pull request from your branch to our origin repository's `main` branch!
|
|
||||||
|
|
||||||
Once you create the pull request, the SailPoint Developer Relations Team will be tagged.
|
1. Fork the repository and copy the `main` branch.
|
||||||
Someone will then review the pull request and merge it in!
|
2. Pull the latest code and ensure that it's running properly.
|
||||||
|
3. Create a new branch from main.
|
||||||
|
- Follow this naming convention for your branch: `feature/your-feature-name`
|
||||||
|
4. Create a pull request from your branch to our origin repository's `main` branch!
|
||||||
|
|
||||||
|
Once you create the pull request, the SailPoint Developer Relations Team will be tagged. Someone will then review the pull request and merge it in!
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
You cannot directly make changes to the API specifications. These files are regularly pulled from a private repository and auto-generated.
|
You cannot directly make changes to the API specifications. These files are regularly pulled from a private repository and auto-generated.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
## Report general issues
|
## Report general issues
|
||||||
|
|
||||||
It's possible that none of the options listed here will properly address your issue.
|
It's possible that none of the options listed here will properly address your issue. If you have a general issue, you can submit a general issue by using GitHub's [issues](https://github.com/sailpoint-oss/developer.sailpoint.com/issues). Add as much detail as you can to your issue, and we will address it as quickly as we can.
|
||||||
If you have a general issue, you can submit a general issue by using GitHub's [issues](https://github.com/sailpoint-oss/developer.sailpoint.com/issues).
|
|
||||||
Add as much detail as you can to your issue, and we will address it as quickly as we can.
|
|
||||||
|
|
||||||
## Discuss on the forum
|
## Discuss on the forum
|
||||||
|
|
||||||
What makes the SailPoint Developer Community great is its brilliant, knowledgeable members!
|
What makes the SailPoint Developer Community great is its brilliant, knowledgeable members! If you have a question, problem, or idea, one of the best ways to get answers or resolutions is to go to the [Developer Community Forum](https://developer.sailpoint.com/discuss) to discuss them directly with the community on the forum. The SailPoint Developer Relations Team, the community ambassadors, and other members will be there to discuss them with you. And once you're there, you can help others on the forum too! If you're interested, you will receive ambassador points for the issues you help others resolve on the forum.Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
||||||
If you have a question, problem, or idea, one of the best ways to get answers or resolutions is to go to the [Developer Community Forum](https://developer.sailpoint.com/discuss) to discuss them directly with the community on the forum.
|
|
||||||
The SailPoint Developer Relations Team, the community ambassadors, and other members will be there to discuss them with you.
|
|
||||||
And once you're there, you can help others on the forum too!
|
|
||||||
If you're interested, you will receive ambassador points for the issues you help others resolve on the forum.Check out the [ambassador program](https://developer.sailpoint.com/discuss/t/getting-started-as-a-developer-community-ambassador/11665) to learn more.
|
|
||||||
|
|
||||||
## MIT Software License
|
## MIT Software License
|
||||||
|
|
||||||
This project uses the [MIT License](http://choosealicense.com/licenses/mit/).
|
This project uses the [MIT License](http://choosealicense.com/licenses/mit/). Whenever you submit code changes, your submissions are held under the same MIT license that covers the project.
|
||||||
Whenever you submit code changes, your submissions are held under the same MIT license that covers the project.
|
|
||||||
|
|||||||
@@ -184,11 +184,7 @@
|
|||||||
"hierarchy.lvl0",
|
"hierarchy.lvl0",
|
||||||
"hierarchy.lvl1"
|
"hierarchy.lvl1"
|
||||||
],
|
],
|
||||||
"searchableAttributes": [
|
"searchableAttributes": ["tags", "hierarchy.lvl0", "hierarchy.lvl1"]
|
||||||
"tags",
|
|
||||||
"hierarchy.lvl0",
|
|
||||||
"hierarchy.lvl1"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"conversation_id": ["1090805758"],
|
"conversation_id": ["1090805758"],
|
||||||
"nb_hits": 8687
|
"nb_hits": 8687
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import md5 from 'crypto-js/md5';
|
|||||||
|
|
||||||
export const URL = 'https://developerdays.sailpoint.com';
|
export const URL = 'https://developerdays.sailpoint.com';
|
||||||
|
|
||||||
|
|
||||||
export async function getFAQ() {
|
export async function getFAQ() {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(URL + '/faq');
|
const response = await fetch(URL + '/faq');
|
||||||
|
|||||||
@@ -149,7 +149,8 @@
|
|||||||
|
|
||||||
.stageButton:disabled {
|
.stageButton:disabled {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
box-shadow: inset -5.0934px -5.0934px 15.2802px rgba(255, 255, 255, 0.5),
|
box-shadow:
|
||||||
|
inset -5.0934px -5.0934px 15.2802px rgba(255, 255, 255, 0.5),
|
||||||
inset 5.0934px 5.0934px 15.2802px rgba(136, 160, 183, 0.25);
|
inset 5.0934px 5.0934px 15.2802px rgba(136, 160, 183, 0.25);
|
||||||
border-radius: 20.3736px;
|
border-radius: 20.3736px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default function ConferenceHero() {
|
|||||||
<div className={styles.center}>
|
<div className={styles.center}>
|
||||||
<div className={styles.mainCard}>
|
<div className={styles.mainCard}>
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.conferenceText}>Developer Days</div>
|
<div className={styles.conferenceText}>Developer Days</div>
|
||||||
<div className={styles.comingSoonText}>March 7th-9th, 2023</div>
|
<div className={styles.comingSoonText}>March 7th-9th, 2023</div>
|
||||||
<div className={styles.descriptionText}>
|
<div className={styles.descriptionText}>
|
||||||
The conference for developers on SailPoint platforms.
|
The conference for developers on SailPoint platforms.
|
||||||
|
|||||||
@@ -15,25 +15,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.conferenceText {
|
.conferenceText {
|
||||||
margin-top: 70px;
|
margin-top: 70px;
|
||||||
font-size: 55px;
|
font-size: 55px;
|
||||||
color: var(--dev-text-color-cobalt);
|
color: var(--dev-text-color-cobalt);
|
||||||
font-family: input-mono;
|
font-family: input-mono;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comingSoonText {
|
.comingSoonText {
|
||||||
color: var(--dev-text-color-cobalt);
|
color: var(--dev-text-color-cobalt);
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-family: input-mono;
|
font-family: input-mono;
|
||||||
letter-spacing: 5.5px;
|
letter-spacing: 5.5px;
|
||||||
margin-top: -17px;
|
margin-top: -17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.descriptionText {
|
.descriptionText {
|
||||||
margin-top: 27px;
|
margin-top: 27px;
|
||||||
color: var(--ifm-color-primary);
|
color: var(--ifm-color-primary);
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
font-family: input-mono;
|
font-family: input-mono;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extensible {
|
.extensible {
|
||||||
@@ -99,4 +99,4 @@
|
|||||||
font-size: 25px;
|
font-size: 25px;
|
||||||
font-family: input-mono;
|
font-family: input-mono;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,16 @@ export default function ConferenceTheme() {
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.center}>
|
<div className={styles.center}>
|
||||||
<div className={styles.gridContainer}>
|
<div className={styles.gridContainer}>
|
||||||
<ThemeCard title={"Developer Days is a hands-on conference, you will build something in almost every session"} image={"/conf/workshops.png"}></ThemeCard>
|
<ThemeCard
|
||||||
<ThemeCard title={"Developer Days will be all-virtual, open to everyone, and <b>at no cost<b>"} image={"/conf/virtual.png"}></ThemeCard>
|
title={
|
||||||
|
'Developer Days is a hands-on conference, you will build something in almost every session'
|
||||||
|
}
|
||||||
|
image={'/conf/workshops.png'}></ThemeCard>
|
||||||
|
<ThemeCard
|
||||||
|
title={
|
||||||
|
'Developer Days will be all-virtual, open to everyone, and <b>at no cost<b>'
|
||||||
|
}
|
||||||
|
image={'/conf/virtual.png'}></ThemeCard>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
.gridContainer {
|
.gridContainer {
|
||||||
display: grid;
|
display: grid;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||||
grid-gap: 40px;
|
grid-gap: 40px;
|
||||||
margin-left: 20px;
|
margin-left: 20px;
|
||||||
margin-right: 40px;
|
margin-right: 40px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
|
|||||||
@@ -148,7 +148,8 @@
|
|||||||
|
|
||||||
.stageButton:disabled {
|
.stageButton:disabled {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
box-shadow: inset -5.0934px -5.0934px 15.2802px rgba(255, 255, 255, 0.5),
|
box-shadow:
|
||||||
|
inset -5.0934px -5.0934px 15.2802px rgba(255, 255, 255, 0.5),
|
||||||
inset 5.0934px 5.0934px 15.2802px rgba(136, 160, 183, 0.25);
|
inset 5.0934px 5.0934px 15.2802px rgba(136, 160, 183, 0.25);
|
||||||
border-radius: 20.3736px;
|
border-radius: 20.3736px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import clsx from "clsx";
|
import clsx from 'clsx';
|
||||||
import styles from "./styles.module.css";
|
import styles from './styles.module.css';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
export default function Video() {
|
export default function Video() {
|
||||||
return (
|
return <div></div>;
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,29 @@
|
|||||||
{
|
{
|
||||||
"name": "delete-test-01",
|
"name": "delete-test-01",
|
||||||
"description": "delete-test-01-description",
|
"description": "delete-test-01-description",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-dynamodb": "^3.188.0",
|
"@aws-sdk/client-dynamodb": "^3.188.0",
|
||||||
"@aws-sdk/lib-dynamodb": "^3.188.0"
|
"@aws-sdk/lib-dynamodb": "^3.188.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"aws-sdk-client-mock": "^2.0.0",
|
"aws-sdk-client-mock": "^2.0.0",
|
||||||
"jest": "^29.2.1"
|
"jest": "^29.2.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js"
|
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
"testMatch": [
|
"testMatch": [
|
||||||
"**/__tests__/**/*.[jt]s?(x)",
|
"**/__tests__/**/*.[jt]s?(x)",
|
||||||
"**/?(*.)+(spec|test).[jt]s?(x)",
|
"**/?(*.)+(spec|test).[jt]s?(x)",
|
||||||
"**/__tests__/**/*.mjs?(x)",
|
"**/__tests__/**/*.mjs?(x)",
|
||||||
"**/?(*.)+(spec|test).mjs?(x)"
|
"**/?(*.)+(spec|test).mjs?(x)"
|
||||||
],
|
],
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
"mjs",
|
"mjs",
|
||||||
"js"
|
"js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
exports.authHandler = async (event) => {
|
exports.authHandler = async (event) => {
|
||||||
const token = event.headers.authorization;
|
const token = event.headers.authorization;
|
||||||
|
|
||||||
const expectedUsername = process.env.AUTH_USERNAME;
|
const expectedUsername = process.env.AUTH_USERNAME;
|
||||||
const expectedPassword = process.env.AUTH_PASSWORD;
|
const expectedPassword = process.env.AUTH_PASSWORD;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { username, password } = decodeAuthToken(token);
|
const {username, password} = decodeAuthToken(token);
|
||||||
if (username === expectedUsername && password === expectedPassword) {
|
if (username === expectedUsername && password === expectedPassword) {
|
||||||
return generatePolicy('user', 'Allow', event.routeArn);
|
return generatePolicy('user', 'Allow', event.routeArn);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unauthorized');
|
throw new Error('Unauthorized');
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log(err.message);
|
|
||||||
return generatePolicy('user', 'Deny', event.routeArn);
|
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err.message);
|
||||||
|
return generatePolicy('user', 'Deny', event.routeArn);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function decodeAuthToken(token) {
|
function decodeAuthToken(token) {
|
||||||
if (!token || !token.startsWith('Basic ')) {
|
if (!token || !token.startsWith('Basic ')) {
|
||||||
throw new Error('Missing or invalid Authorization header');
|
throw new Error('Missing or invalid Authorization header');
|
||||||
}
|
}
|
||||||
|
|
||||||
const base64Credentials = token.split(' ')[1];
|
const base64Credentials = token.split(' ')[1];
|
||||||
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
|
const credentials = Buffer.from(base64Credentials, 'base64').toString(
|
||||||
const [username, password] = credentials.split(':');
|
'ascii',
|
||||||
return { username, password };
|
);
|
||||||
|
const [username, password] = credentials.split(':');
|
||||||
|
return {username, password};
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePolicy(principalId, effect, resource) {
|
function generatePolicy(principalId, effect, resource) {
|
||||||
return {
|
return {
|
||||||
principalId,
|
principalId,
|
||||||
policyDocument: {
|
policyDocument: {
|
||||||
Version: '2012-10-17',
|
Version: '2012-10-17',
|
||||||
Statement: [
|
Statement: [
|
||||||
{
|
{
|
||||||
Action: 'execute-api:Invoke',
|
Action: 'execute-api:Invoke',
|
||||||
Effect: effect,
|
Effect: effect,
|
||||||
Resource: resource
|
Resource: resource,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ slug: /api/api-specifications
|
|||||||
tags: ['API Specifications']
|
tags: ['API Specifications']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The Identity Security Cloud (ISC) APIs provide developers with a way to interact with the ISC platform and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
The Identity Security Cloud (ISC) APIs provide developers with a way to interact with the ISC platform and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
||||||
|
|
||||||
The API specifications contain detailed information of how to send requests to each API endpoint, as well as example requests and responses. They also include essential information about how to use the APIs and guides you can follow to get started.
|
The API specifications contain detailed information of how to send requests to each API endpoint, as well as example requests and responses. They also include essential information about how to use the APIs and guides you can follow to get started.
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
import DocCardList from '@theme/DocCardList';
|
import DocCardList from '@theme/DocCardList';
|
||||||
@@ -24,8 +24,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
|
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
To learn more about the ISC APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tags/c/isc/6/apis).
|
To learn more about the ISC APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tags/c/isc/6/apis).
|
||||||
|
|||||||
@@ -15,20 +15,13 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
With SailPoint's Identity Security Cloud (ISC) APIs, you can extend your ISC platform far beyond its current capabilities.
|
With SailPoint's Identity Security Cloud (ISC) APIs, you can extend your ISC platform far beyond its current capabilities. To be able to do so, you must first authenticate to the ISC APIs. Authentication is the act of validating a user's identity, generally by passing some kind of credentials. A fast, simple way to authenticate to the APIs is to generate a [personal access token](#generate-a-personal-access-token) and pass that token.
|
||||||
|
|
||||||
To be able to do so, you must first authenticate to the ISC APIs.
|
|
||||||
Authentication is the act of validating a user's identity, generally by passing some kind of credentials.
|
|
||||||
A fast, simple way to authenticate to the APIs is to generate a [personal access token](#generate-a-personal-access-token) and pass that token.
|
|
||||||
|
|
||||||
If the PAT is valid, the API responds with a JSON Web Token (JWT) `access_token` that you can provide to authorize your API requests.
|
If the PAT is valid, the API responds with a JSON Web Token (JWT) `access_token` that you can provide to authorize your API requests. Authorization is the act of validating the user's permission to access a given resource. A successful API request must include the `access_token` in the `Authorization` request header.
|
||||||
Authorization is the act of validating the user's permission to access a given resource.
|
|
||||||
A successful API request must include the `access_token` in the `Authorization` request header.
|
|
||||||
|
|
||||||
This JWT `access_token` grants access matching that of the user who generated the PAT.
|
This JWT `access_token` grants access matching that of the user who generated the PAT. For example, if the user who generated the PAT is an admin, the returned JWT `access_token` would grant admin access to the APIs.
|
||||||
For example, if the user who generated the PAT is an admin, the returned JWT `access_token` would grant admin access to the APIs.
|
|
||||||
|
|
||||||
This diagram shows the flow of this authentication/authorization process:
|
This diagram shows the flow of this authentication/authorization process:
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
@@ -49,23 +42,23 @@ sequenceDiagram
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The flow involves these four key steps:
|
The flow involves these four key steps:
|
||||||
1. **Access Token Request**: The HTTP client (a script, application, Postman, cURL, etc.) makes a request to ISC to get a JWT `access_token`.
|
|
||||||
2. **Access Token Response**: If the request is valid, ISC responds to the HTTP client with a JWT `access_token`.
|
|
||||||
3. **API Request**: The HTTP client makes a request to an ISC endpoint with the header, `Authorization: Bearer {access_token}`.
|
|
||||||
4. **API Response**: If both the request itself and the JWT `access_token` in its header are valid, ISC responds to the client.
|
|
||||||
If you encounter unexpected errors, refer to the [Troubleshooting](#troubleshooting) section of this document.
|
|
||||||
|
|
||||||
The idea is that once you have authenticated to the ISC APIs and you have received an `access_token`, you can use that `access_token` to provide authorization for your API requests.
|
1. **Access Token Request**: The HTTP client (a script, application, Postman, cURL, etc.) makes a request to ISC to get a JWT `access_token`.
|
||||||
|
2. **Access Token Response**: If the request is valid, ISC responds to the HTTP client with a JWT `access_token`.
|
||||||
|
3. **API Request**: The HTTP client makes a request to an ISC endpoint with the header, `Authorization: Bearer {access_token}`.
|
||||||
|
4. **API Response**: If both the request itself and the JWT `access_token` in its header are valid, ISC responds to the client. If you encounter unexpected errors, refer to the [Troubleshooting](#troubleshooting) section of this document.
|
||||||
|
|
||||||
This document includes all the information you need to know to engage in this authentication/authorization process, as well as a guide on how to get started.
|
The idea is that once you have authenticated to the ISC APIs and you have received an `access_token`, you can use that `access_token` to provide authorization for your API requests.
|
||||||
|
|
||||||
|
This document includes all the information you need to know to engage in this authentication/authorization process, as well as a guide on how to get started.
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
Read this guide to learn how to authenticate to SailPoint's ISC APIs.
|
Read this guide to learn how to authenticate to SailPoint's ISC APIs.
|
||||||
|
|
||||||
|
To authenticate to the ISC APIs, you must be able to connect to your tenant to send the access token request. To do so, you need to do the following:
|
||||||
|
|
||||||
To authenticate to the ISC APIs, you must be able to connect to your tenant to send the access token request.
|
|
||||||
To do so, you need to do the following:
|
|
||||||
1. [Find your tenant's OAuth details](#find-your-tenant's-oauth-details)
|
1. [Find your tenant's OAuth details](#find-your-tenant's-oauth-details)
|
||||||
2. [Generate personal access token](#generate-personal-access-token)
|
2. [Generate personal access token](#generate-personal-access-token)
|
||||||
3. [Choose authorization grant flow](#choose-authorization-grant-flow)
|
3. [Choose authorization grant flow](#choose-authorization-grant-flow)
|
||||||
@@ -73,21 +66,19 @@ To do so, you need to do the following:
|
|||||||
|
|
||||||
### Find your tenant's OAuth details
|
### Find your tenant's OAuth details
|
||||||
|
|
||||||
Your tenant's OAuth details refer to the details you need to know to connect it to the APIs.
|
Your tenant's OAuth details refer to the details you need to know to connect it to the APIs. You need to know your tenant's name, its `authorizeEndpoint` URL, and its `tokenEndpoint` URL.
|
||||||
You need to know your tenant's name, its `authorizeEndpoint` URL, and its `tokenEndpoint` URL.
|
|
||||||
|
|
||||||
Your ISC instance is likely using the domain name supplied by SailPoint (`{tenant}.api.identitynow.com`), in which case, the tenant name is in the URL.
|
Your ISC instance is likely using the domain name supplied by SailPoint (`{tenant}.api.identitynow.com`), in which case, the tenant name is in the URL. This is assumed to be the case in this guide.
|
||||||
This is assumed to be the case in this guide.
|
However, if your ISC instance is using a vanity URL, you must enter this URL into your browser to get your OAuth info: `https://{tenant}.api.identitynow.com/oauth/info`
|
||||||
However, if your ISC instance is using a vanity URL, you must enter this URL into your browser to get your OAuth info:
|
|
||||||
`https://{tenant}.api.identitynow.com/oauth/info`
|
If you have admin access but don't know your tenant name, you can learn it by following these steps:
|
||||||
|
|
||||||
If you have admin access but don't know your tenant name, you can learn it by following these steps:
|
|
||||||
1. Log into your ISC instance.
|
1. Log into your ISC instance.
|
||||||
2. Select the 'Dashboard' dropdown.
|
2. Select the 'Dashboard' dropdown.
|
||||||
3. Select 'Overview'.
|
3. Select 'Overview'.
|
||||||
4. Find the tenant name ('Org Name') in the dashboard's `Org Details` section.
|
4. Find the tenant name ('Org Name') in the dashboard's `Org Details` section.
|
||||||
|
|
||||||
This is an example of the OAuth details of the tenant, "iga-acme-sb":
|
This is an example of the OAuth details of the tenant, "iga-acme-sb":
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -101,25 +92,21 @@ This is an example of the OAuth details of the tenant, "iga-acme-sb":
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use the `authorizeEndpoint` and `tokenEndpoint` URLs from this example to test out the different authentication methods listed in this guide.
|
You can use the `authorizeEndpoint` and `tokenEndpoint` URLs from this example to test out the different authentication methods listed in this guide.
|
||||||
|
|
||||||
### Generate a personal access token
|
### Generate a personal access token
|
||||||
|
|
||||||
A personal access token (PAT) is a method of authenticating to an API as a user without providing a username and password.
|
A personal access token (PAT) is a method of authenticating to an API as a user without providing a username and password. PATs are primarily used in scripts or programs that lack an easy way to implement an OAuth2 flow but need to call API endpoints that require user context. PATs are also convenient for use in tools like [Postman](https://www.postman.com/) when you are exploring and testing the APIs.
|
||||||
PATs are primarily used in scripts or programs that lack an easy way to implement an OAuth2 flow but need to call API endpoints that require user context.
|
|
||||||
PATs are also convenient for use in tools like [Postman](https://www.postman.com/) when you are exploring and testing the APIs.
|
|
||||||
|
|
||||||
Any ISC user can generate a PAT.
|
Any ISC user can generate a PAT. To do so, follow these steps:
|
||||||
To do so, follow these steps:
|
|
||||||
1. Select **Preferences** from the drop-down menu under your username, then **Personal Access Tokens** on the left.
|
1. Select **Preferences** from the drop-down menu under your username, then **Personal Access Tokens** on the left. You can also go directly to the page by using this URL (replace `{tenant}` with your Identity Security Cloud tenant): `https://{tenant}.identitynow.com/ui/d/user-preferences/personal-access-tokens`
|
||||||
You can also go directly to the page by using this URL (replace `{tenant}` with your Identity Security Cloud tenant): `https://{tenant}.identitynow.com/ui/d/user-preferences/personal-access-tokens`
|
|
||||||
|
|
||||||
2. Click **New Token** and enter a meaningful description to help differentiate the token from others.
|
2. Click **New Token** and enter a meaningful description to help differentiate the token from others.
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
|
|
||||||
The **New Token** button will be disabled when you reach the limit of 10 personal access tokens per user.
|
The **New Token** button will be disabled when you reach the limit of 10 personal access tokens per user. To avoid reaching this limit, it is recommended that you delete any tokens that are no longer necessary.
|
||||||
To avoid reaching this limit, it is recommended that you delete any tokens that are no longer necessary.
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -135,29 +122,25 @@ After you create the token, the value of the `Client ID` will be visible in the
|
|||||||
|
|
||||||
To generate a personal access token from the API, use the [create personal access token endpoint](/docs/api/beta/create-personal-access-token).
|
To generate a personal access token from the API, use the [create personal access token endpoint](/docs/api/beta/create-personal-access-token).
|
||||||
|
|
||||||
Once you have created the PAT and you know its `Client ID` and `Client Secret`, you have everything you need to follow the [Client Credentials Grant Flow](#request-access-token-with-client-credentials-grant-flow) and use the PAT to generate an `access_token`.
|
Once you have created the PAT and you know its `Client ID` and `Client Secret`, you have everything you need to follow the [Client Credentials Grant Flow](#request-access-token-with-client-credentials-grant-flow) and use the PAT to generate an `access_token`. You will need this `access_token` to authenticate your requests to the APIs.
|
||||||
You will need this `access_token` to authenticate your requests to the APIs.
|
|
||||||
|
|
||||||
### Choose authorization grant flow
|
### Choose authorization grant flow
|
||||||
|
|
||||||
There are several different authorization flows that OAuth 2.0 supports, and each has a grant-type defining its different use cases.
|
There are several different authorization flows that OAuth 2.0 supports, and each has a grant-type defining its different use cases. You must choose the one that best serves your purposes. This document covers these three common flows:
|
||||||
You must choose the one that best serves your purposes.
|
|
||||||
This document covers these three common flows:
|
|
||||||
|
|
||||||
1. [**Client Credentials**](https://oauth.net/2/grant-types/client-credentials/) - Clients use this grant type to obtain a JWT `access_token` without user involvement such as scripts, programs or system to system integration.
|
1. [**Client Credentials**](https://oauth.net/2/grant-types/client-credentials/) - Clients use this grant type to obtain a JWT `access_token` without user involvement such as scripts, programs or system to system integration.
|
||||||
2. [**Authorization Code**](https://oauth.net/2/grant-types/authorization-code/) - Clients use this grant type to exchange an authorization code for an `access_token`. Authorization codes are mainly used by web applications because there is a login into ISC with a subsequent redirect back to the web application/client.
|
2. [**Authorization Code**](https://oauth.net/2/grant-types/authorization-code/) - Clients use this grant type to exchange an authorization code for an `access_token`. Authorization codes are mainly used by web applications because there is a login into ISC with a subsequent redirect back to the web application/client.
|
||||||
3. [**Refresh Token**](https://oauth.net/2/grant-types/refresh-token/) - Clients use this grant type to exchange a refresh token for a new `access_token` when the existing `access_token` has expired. This allows clients to continue using the APIs without having to re-authenticate as frequently. This grant type is commonly used together with `Authorization Code` to prevent a user from having to log in several times per day.
|
3. [**Refresh Token**](https://oauth.net/2/grant-types/refresh-token/) - Clients use this grant type to exchange a refresh token for a new `access_token` when the existing `access_token` has expired. This allows clients to continue using the APIs without having to re-authenticate as frequently. This grant type is commonly used together with `Authorization Code` to prevent a user from having to log in several times per day.
|
||||||
|
|
||||||
One way to determine which authorization flow you need to use is to look at the specification for the endpoint you want to use.
|
One way to determine which authorization flow you need to use is to look at the specification for the endpoint you want to use. The endpoint will have the supported OAuth flows listed under the 'Authorization' dropdown, like the [List Access Profiles endpoint](https://developer.sailpoint.com/docs/api/beta/list-access-profiles):
|
||||||
The endpoint will have the supported OAuth flows listed under the 'Authorization' dropdown, like the [List Access Profiles endpoint](https://developer.sailpoint.com/docs/api/beta/list-access-profiles):
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
For more information about how to choose the best grant flow for your use case, refer to [Grant Flow Use Cases](#grant-flow-use-cases)
|
For more information about how to choose the best grant flow for your use case, refer to [Grant Flow Use Cases](#grant-flow-use-cases)
|
||||||
|
|
||||||
The guide will detail the three different authorization grant flows you can use to request the access token you need to authenticate your requests.
|
The guide will detail the three different authorization grant flows you can use to request the access token you need to authenticate your requests.
|
||||||
|
|
||||||
### Request access token with client credentials grant flow
|
### Request access token with client credentials grant flow
|
||||||
|
|
||||||
Clients use the 'Client Credentials' grant type to obtain access tokens without user involvement. This is the simplest authentication flow.
|
Clients use the 'Client Credentials' grant type to obtain access tokens without user involvement. This is the simplest authentication flow.
|
||||||
|
|
||||||
@@ -185,25 +168,25 @@ An OAuth 2.0 client using the client credentials grant flow must have `CLIENT_CR
|
|||||||
This is the overall authorization flow:
|
This is the overall authorization flow:
|
||||||
|
|
||||||
1. The client first submits an OAuth 2.0 token request to ISC in this form:
|
1. The client first submits an OAuth 2.0 token request to ISC in this form:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
POST https://{tenant}.api.identitynow.com/oauth/token
|
POST https://{tenant}.api.identitynow.com/oauth/token
|
||||||
```
|
```
|
||||||
|
|
||||||
The request includes the client credential information passed in the request body, as shown in this example using [Postman](https://www.getpostman.com):
|
The request includes the client credential information passed in the request body, as shown in this example using [Postman](https://www.getpostman.com):
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
This example shows how to pass the information with form-data in the request body. You can also use these options to pass in the information:
|
This example shows how to pass the information with form-data in the request body. You can also use these options to pass in the information:
|
||||||
|
|
||||||
- Use x-www-form-urlencoded data to pass in the client credential information in the request body.
|
- Use x-www-form-urlencoded data to pass in the client credential information in the request body.
|
||||||
- Use query parameters to pass the information in the request URL. The request URL will look like this:
|
- Use query parameters to pass the information in the request URL. The request URL will look like this:
|
||||||
```text
|
```text
|
||||||
https://{tenant}.api.identitynow.com/oauth/token?grant_type=client_credentials&client_id={{clientId}}&client_secret={{clientSecret}}
|
https://{tenant}.api.identitynow.com/oauth/token?grant_type=client_credentials&client_id={{clientId}}&client_secret={{clientSecret}}
|
||||||
```
|
```
|
||||||
- If you are using Postman, you can use the 'Authorization' tab to pass in the client credentials. If you use this option, you must also specify the access token URL: https://{tenant}.api.identitynow.com/oauth/token
|
- If you are using Postman, you can use the 'Authorization' tab to pass in the client credentials. If you use this option, you must also specify the access token URL: https://{tenant}.api.identitynow.com/oauth/token
|
||||||
|
|
||||||
The OAuth 2.0 token request must include this information:
|
The OAuth 2.0 token request must include this information:
|
||||||
|
|
||||||
| Key | Description |
|
| Key | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -221,23 +204,19 @@ curl --location 'https://{tenant}.api.identitynow.com/oauth/token' \
|
|||||||
--form 'client_secret="{clientSecret}"'
|
--form 'client_secret="{clientSecret}"'
|
||||||
```
|
```
|
||||||
|
|
||||||
2. ISC validates the token request and responds.
|
2. ISC validates the token request and responds. If the request is successful, the response contains a JWT access token. For more information about the JWT access token in the response, refer to [#OAuth-token-response](#oauth-token-response).
|
||||||
If the request is successful, the response contains a JWT access token.
|
|
||||||
For more information about the JWT access token in the response, refer to [#OAuth-token-response](#oauth-token-response).
|
|
||||||
|
|
||||||
Once you have the JWT access token, you can pass the token as a basic "Authorization" header in your requests using the OAuth endpoints.
|
Once you have the JWT access token, you can pass the token as a basic "Authorization" header in your requests using the OAuth endpoints.
|
||||||
|
|
||||||
To learn more about the OAuth client credentials grant flow, refer [here](https://oauth.net/2/grant-types/client-credentials/).
|
To learn more about the OAuth client credentials grant flow, refer [here](https://oauth.net/2/grant-types/client-credentials/).
|
||||||
|
|
||||||
### Request access token with authorization code grant flow
|
### Request access token with authorization code grant flow
|
||||||
|
|
||||||
Further Reading: [https://oauth.net/2/grant-types/authorization-code/](https://oauth.net/2/grant-types/authorization-code/)
|
Further Reading: [https://oauth.net/2/grant-types/authorization-code/](https://oauth.net/2/grant-types/authorization-code/)
|
||||||
|
|
||||||
Clients use this grant type to exchange an authorization code for an `access_token`.
|
Clients use this grant type to exchange an authorization code for an `access_token`. This is mainly used for web apps because there is a login into ISC with a subsequent redirect back to the web app/client.
|
||||||
This is mainly used for web apps because there is a login into ISC with a subsequent redirect back to the web app/client.
|
|
||||||
|
|
||||||
The OAuth 2.0 client you are using must have `AUTHORIZATION_CODE` as one of its grant types.
|
The OAuth 2.0 client you are using must have `AUTHORIZATION_CODE` as one of its grant types. The redirect URLs must also match the list in the client as well:
|
||||||
The redirect URLs must also match the list in the client as well:
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -258,9 +237,9 @@ The redirect URLs must also match the list in the client as well:
|
|||||||
|
|
||||||
<br></br>
|
<br></br>
|
||||||
|
|
||||||
The authorization code grant flow looks a little different because it involves the exchange of the access token and authorization code.
|
The authorization code grant flow looks a little different because it involves the exchange of the access token and authorization code.
|
||||||
|
|
||||||
This diagram shows the authorization code grant flow:
|
This diagram shows the authorization code grant flow:
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
@@ -310,8 +289,7 @@ The token endpoint URL is `{tenant}.api.identitynow.com`, and the authorize URL
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
7. ISC validates the token request and submits a response. If the request is successful, the response contains a JWT `access_token`.
|
7. ISC validates the token request and submits a response. If the request is successful, the response contains a JWT `access_token`. For more information about the JWT access token in the response, refer to [#OAuth-token-response](#oauth-token-response).
|
||||||
For more information about the JWT access token in the response, refer to [#OAuth-token-response](#oauth-token-response).
|
|
||||||
|
|
||||||
These are the query parameters in the OAuth 2.0 token request for the authorization code grant:
|
These are the query parameters in the OAuth 2.0 token request for the authorization code grant:
|
||||||
|
|
||||||
@@ -328,14 +306,14 @@ Here is an example OAuth 2.0 token request for the authorization code grant type
|
|||||||
curl -X POST \
|
curl -X POST \
|
||||||
'https://example.api.identitynow.com/oauth/token?grant_type=authorization_code&client_id=b61429f5-203d-494c-94c3-04f54e17bc5c&code=6688LQJB0y652z6ZjFmkCKuBUjv2sTIqKS2JthWrZ7qlPgI9TClJ6FnpweEhO6w7&redirect_uri=https://myappdomain.com/oauth/redirect' \
|
'https://example.api.identitynow.com/oauth/token?grant_type=authorization_code&client_id=b61429f5-203d-494c-94c3-04f54e17bc5c&code=6688LQJB0y652z6ZjFmkCKuBUjv2sTIqKS2JthWrZ7qlPgI9TClJ6FnpweEhO6w7&redirect_uri=https://myappdomain.com/oauth/redirect' \
|
||||||
-H 'cache-control: no-cache'
|
-H 'cache-control: no-cache'
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you have the JWT access token, you can pass the token as a basic "Authorization" header in your requests using the OAuth endpoints.
|
Once you have the JWT access token, you can pass the token as a basic "Authorization" header in your requests using the OAuth endpoints.
|
||||||
|
|
||||||
For more information about the OAuth authorization code grant flow, refer [here](https://oauth.net/2/grant-types/authorization-code/).
|
For more information about the OAuth authorization code grant flow, refer [here](https://oauth.net/2/grant-types/authorization-code/).
|
||||||
|
|
||||||
### Request access token with refresh token grant flow
|
### Request access token with refresh token grant flow
|
||||||
|
|
||||||
Clients use this grant type in order to exchange a refresh token for a new `access_token` once the existing `access_token` has expired. This allows clients to continue to have a valid `access_token` without the need for the user to login as frequently.
|
Clients use this grant type in order to exchange a refresh token for a new `access_token` once the existing `access_token` has expired. This allows clients to continue to have a valid `access_token` without the need for the user to login as frequently.
|
||||||
|
|
||||||
@@ -386,9 +364,9 @@ curl -X POST \
|
|||||||
-H 'cache-control: no-cache'
|
-H 'cache-control: no-cache'
|
||||||
```
|
```
|
||||||
|
|
||||||
Once you have the `refresh_token`, you can pass the `refresh_token` as a basic "Authorization" header in your requests using the OAuth endpoints, allowing your requests to continue to succeed without being affected by the expired `access_token`.
|
Once you have the `refresh_token`, you can pass the `refresh_token` as a basic "Authorization" header in your requests using the OAuth endpoints, allowing your requests to continue to succeed without being affected by the expired `access_token`.
|
||||||
|
|
||||||
For more information about the OAuth refresh token grant flow, refer [here](https://oauth.net/2/grant-types/refresh-token/).
|
For more information about the OAuth refresh token grant flow, refer [here](https://oauth.net/2/grant-types/refresh-token/).
|
||||||
|
|
||||||
### OAuth token response
|
### OAuth token response
|
||||||
|
|
||||||
@@ -415,9 +393,7 @@ A successful request using any of the grant flows to `https://{tenant}.api.ident
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can use the JWT `access_token` to authorize REST API calls through the ISC API gateway.
|
You can use the JWT `access_token` to authorize REST API calls through the ISC API gateway. To use the `access_token`, simply include it in the `Authorization` header as a `Bearer` token. This is an example V3 API request that has the access token in the header:
|
||||||
To use the `access_token`, simply include it in the `Authorization` header as a `Bearer` token.
|
|
||||||
This is an example V3 API request that has the access token in the header:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X GET \
|
curl -X GET \
|
||||||
@@ -426,34 +402,27 @@ curl -X GET \
|
|||||||
-H 'cache-control: no-cache'
|
-H 'cache-control: no-cache'
|
||||||
```
|
```
|
||||||
|
|
||||||
Some of the other values can also be useful to know:
|
Some of the other values can also be useful to know:
|
||||||
- The `expires_in` value describes the lifetime, in seconds, of the `access_token`.
|
|
||||||
For example, the value 749 means that the `access_token` will expire 12.5 minutes from the time the response was generated.
|
|
||||||
The exact expiration date is also contained within the `access_token`.
|
|
||||||
You can view this expiration time by decoding the JWT `access_token` using a tool like [jwt.io](https://jwt.io/).
|
|
||||||
|
|
||||||
- The `refresh token` exists for use in the refresh token grant flow to replace the `access_token` when it expires.
|
- The `expires_in` value describes the lifetime, in seconds, of the `access_token`. For example, the value 749 means that the `access_token` will expire 12.5 minutes from the time the response was generated. The exact expiration date is also contained within the `access_token`. You can view this expiration time by decoding the JWT `access_token` using a tool like [jwt.io](https://jwt.io/).
|
||||||
However, the `refresh_token` will only be present if the API client has the `REFRESH_TOKEN` grant flow.
|
|
||||||
|
|
||||||
- The `user_id` and `identity_id` define the identity context of the person who authenticated.
|
- The `refresh token` exists for use in the refresh token grant flow to replace the `access_token` when it expires. However, the `refresh_token` will only be present if the API client has the `REFRESH_TOKEN` grant flow.
|
||||||
However, these values aren't set for the client credentials grant type because it doesn't have a user context.
|
|
||||||
|
|
||||||
With the JWT `access_token`, you can now successfully send authenticated ISC API requests. To learn more about authorization and the scopes you can apply to further control access to the APIs, refer to [Authorization](/docs/api/authorization).
|
- The `user_id` and `identity_id` define the identity context of the person who authenticated. However, these values aren't set for the client credentials grant type because it doesn't have a user context.
|
||||||
|
|
||||||
|
With the JWT `access_token`, you can now successfully send authenticated ISC API requests. To learn more about authorization and the scopes you can apply to further control access to the APIs, refer to [Authorization](/docs/api/authorization).
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
|
||||||
This section of the document includes additional information about the authentication/authorization process, including some different use cases for the different authorization grant flows.
|
This section of the document includes additional information about the authentication/authorization process, including some different use cases for the different authorization grant flows.
|
||||||
|
|
||||||
### OAuth 2.0
|
### OAuth 2.0
|
||||||
The SailPoint authentication/authorization model is fully [OAuth 2.0](https://oauth.net/2/) compliant.
|
|
||||||
[OAuth 2.0](https://oauth.net/2/) is an industry-standard protocol for authorization.
|
The SailPoint authentication/authorization model is fully [OAuth 2.0](https://oauth.net/2/) compliant. [OAuth 2.0](https://oauth.net/2/) is an industry-standard protocol for authorization. It provides a variety of authorization flows for web applications, desktop applications, mobile phones, and devices. This specification and its extensions are developed within the [IETF OAuth Working Group](https://www.ietf.org/mailman/listinfo/oauth).
|
||||||
It provides a variety of authorization flows for web applications, desktop applications, mobile phones, and devices.
|
|
||||||
This specification and its extensions are developed within the [IETF OAuth Working Group](https://www.ietf.org/mailman/listinfo/oauth).
|
|
||||||
|
|
||||||
### JSON Web Token
|
### JSON Web Token
|
||||||
The issued JWT `access_token` leverages the [JSON Web Token (JWT)](https://jwt.io/) standard.
|
|
||||||
JWT is an industry-standard protocol for creating access tokens which assert various claims about the resource who has authenticated.
|
The issued JWT `access_token` leverages the [JSON Web Token (JWT)](https://jwt.io/) standard. JWT is an industry-standard protocol for creating access tokens which assert various claims about the resource who has authenticated. The tokens have a specific structure consisting of a header, payload, and signature.
|
||||||
The tokens have a specific structure consisting of a header, payload, and signature.
|
|
||||||
|
|
||||||
A raw JWT might look like this:
|
A raw JWT might look like this:
|
||||||
|
|
||||||
@@ -513,43 +482,43 @@ You can check the JWT access token data online at [jwt.io](https://jwt.io).
|
|||||||
|
|
||||||
### Grant flow use cases
|
### Grant flow use cases
|
||||||
|
|
||||||
This section describes some different use cases and which grant flow you would want to use for the different cases.
|
This section describes some different use cases and which grant flow you would want to use for the different cases.
|
||||||
|
|
||||||
#### Daily work or quick actions
|
#### Daily work or quick actions
|
||||||
|
|
||||||
For daily work or short, quick administrative actions, you can just use a PAT. This makes the process easier because you don't really need to worry about grant types - you can easily generate a PAT in the user interface (UI).
|
For daily work or short, quick administrative actions, you can just use a PAT. This makes the process easier because you don't really need to worry about grant types - you can easily generate a PAT in the user interface (UI).
|
||||||
|
|
||||||
Follow these steps to do so:
|
Follow these steps to do so:
|
||||||
|
|
||||||
1. Log in to ISC.
|
1. Log in to ISC.
|
||||||
2. Go to 'Preferences', then 'Personal Access Tokens', and [generate a PAT](#generate-a-personal-access-token).
|
2. Go to 'Preferences', then 'Personal Access Tokens', and [generate a PAT](#generate-a-personal-access-token).
|
||||||
3. The PAT's `client_id` and `client_secret` provide the necessary authentication to send API requests, without any grant flow.
|
3. The PAT's `client_id` and `client_secret` provide the necessary authentication to send API requests, without any grant flow.
|
||||||
|
|
||||||
#### Postman
|
#### Postman
|
||||||
|
|
||||||
[Postman](https://www.postman.com/) is a popular HTTP client you can use to design, build, test, and iterate your APIs. Postman users and teams can create public workspaces they can use to make it easy to access their API collections and environments and get started. SailPoint maintains a [public workspace for the Identity Security Cloud API collections](https://www.postman.com/sailpoint/workspace/identitynow). You can use this workspace to access all the ISC API collections and stay up to date.
|
[Postman](https://www.postman.com/) is a popular HTTP client you can use to design, build, test, and iterate your APIs. Postman users and teams can create public workspaces they can use to make it easy to access their API collections and environments and get started. SailPoint maintains a [public workspace for the Identity Security Cloud API collections](https://www.postman.com/sailpoint/workspace/identitynow). You can use this workspace to access all the ISC API collections and stay up to date.
|
||||||
|
|
||||||
If you're using Postman, you have some different ways to set up your authorization.
|
If you're using Postman, you have some different ways to set up your authorization. You can just leverage the accessToken as mentioned above, or you can configure Postman to use OAuth 2.0 directly. For more information about how to do so, refer [here](https://learning.postman.com/docs/sending-requests/authorization/).
|
||||||
You can just leverage the accessToken as mentioned above, or you can configure Postman to use OAuth 2.0 directly.
|
|
||||||
For more information about how to do so, refer [here](https://learning.postman.com/docs/sending-requests/authorization/).
|
#### Web applications
|
||||||
|
|
||||||
#### Web applications
|
|
||||||
If you are making a web application, the best grant flow to use is the [Authorization Code grant flow](#request-access-token-with-authorization-grant-flow). This will allow users to be directed to ISC to login and then redirected back to the web application through a URL redirect. This also works well with Single Sign-on (SSO), strong authentication, and pass-through authentication mechanisms.
|
If you are making a web application, the best grant flow to use is the [Authorization Code grant flow](#request-access-token-with-authorization-grant-flow). This will allow users to be directed to ISC to login and then redirected back to the web application through a URL redirect. This also works well with Single Sign-on (SSO), strong authentication, and pass-through authentication mechanisms.
|
||||||
|
|
||||||
SailPoint doesn't recommend using a password grant flow for web applications because doing so would involve entering ISC credentials in the web application.
|
SailPoint doesn't recommend using a password grant flow for web applications because doing so would involve entering ISC credentials in the web application. This flow also doesn't allow you to work with SSO, strong authentication, or pass-through authentication.
|
||||||
This flow also doesn't allow you to work with SSO, strong authentication, or pass-through authentication.
|
|
||||||
|
|
||||||
#### Scripts, programs or system to system integration
|
#### Scripts, programs or system to system integration
|
||||||
If you are writing scripts, programs or system integrations that leverage the ISC APIs, the OAuth 2.0 grant you should use typically depends on what you're doing and the user context you need to operate under.
|
|
||||||
|
If you are writing scripts, programs or system integrations that leverage the ISC APIs, the OAuth 2.0 grant you should use typically depends on what you're doing and the user context you need to operate under.
|
||||||
|
|
||||||
Because scripts, code, and programs lack an interactive web-interface, it is difficult, but not impossible, to implement a working authorization code grant flow. System to system integrations may require an elevated level of access and utilize a service account to make API calls beyond the privileges of the authenticated user.
|
Because scripts, code, and programs lack an interactive web-interface, it is difficult, but not impossible, to implement a working authorization code grant flow. System to system integrations may require an elevated level of access and utilize a service account to make API calls beyond the privileges of the authenticated user.
|
||||||
|
|
||||||
Most scripts, programs, and many integrations use the [Client Credentials grant flow](#request-access-token-with-client-credentials-grant-flow).
|
Most scripts, programs, and many integrations use the [Client Credentials grant flow](#request-access-token-with-client-credentials-grant-flow). Using a PAT allows your API calls to work within a user context making client credentials ideal.
|
||||||
Using a PAT allows your API calls to work within a user context making client credentials ideal.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
Having issues? Follow these steps:
|
Having issues? Follow these steps:
|
||||||
|
|
||||||
### Verify API endpoint calls
|
### Verify API endpoint calls
|
||||||
|
|
||||||
1. Verify the structure of the API call:
|
1. Verify the structure of the API call:
|
||||||
2. Verify that the API calls are going through the API gateway: `https://{tenant}.api.identitynow.com`
|
2. Verify that the API calls are going through the API gateway: `https://{tenant}.api.identitynow.com`
|
||||||
@@ -566,16 +535,15 @@ Having issues? Follow these steps:
|
|||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
|
||||||
You can also get a **403 Forbidden** response error when you call an API that expects a user, but your authorization grant type lacks a user context. Calling most admin APIs with a `CLIENT_CREDENTIAL` grant often produces this result.
|
You can also get a **403 Forbidden** response error when you call an API that expects a user, but your authorization grant type lacks a user context. Calling most admin APIs with a `CLIENT_CREDENTIAL` grant often produces this result.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
### Verify OAuth client
|
### Verify OAuth client
|
||||||
|
|
||||||
1. Verify that the OAuth 2.0 client is not a legacy OAuth client. Legacy OAuth clients will not work. This can become very apparent when you look at the client ID - OAuth 2.0 client IDs have dashes.
|
1. Verify that the OAuth 2.0 client is not a legacy OAuth client. Legacy OAuth clients will not work. This can become very apparent when you look at the client ID - OAuth 2.0 client IDs have dashes. Here are two examples that illustrate the difference:
|
||||||
Here are two examples that illustrate the difference:
|
|
||||||
|
|
||||||
Legacy Client ID: `G6xLlBBOKIcOAQuK`
|
Legacy Client ID: `G6xLlBBOKIcOAQuK`
|
||||||
|
|
||||||
OAuth 2.0 Client ID: `b61429f5-203d-494c-94c3-04f54e17bc5c`
|
OAuth 2.0 Client ID: `b61429f5-203d-494c-94c3-04f54e17bc5c`
|
||||||
|
|
||||||
@@ -611,10 +579,8 @@ You can also view all of the active clients in the UI by going to `https://{tena
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
4. If you're using an [Authorization Code](#authorization-code-grant-flow) grant flow, verify that the redirect URL(s) for your application match the `redirectUris` value in the client.
|
4. If you're using an [Authorization Code](#authorization-code-grant-flow) grant flow, verify that the redirect URL(s) for your application match the `redirectUris` value in the client. You can check this by calling the [List OAuth Clients endpoint](/docs/api/beta/list-oauth-clients).
|
||||||
You can check this by calling the [List OAuth Clients endpoint](/docs/api/beta/list-oauth-clients).
|
|
||||||
|
|
||||||
### Verify OAuth calls
|
### Verify OAuth calls
|
||||||
Verify that the OAuth call flow is going to the right URLs, with the correct query parameters and data values.
|
|
||||||
A common source of errors is using the wrong host for authorization and token API calls.
|
Verify that the OAuth call flow is going to the right URLs, with the correct query parameters and data values. A common source of errors is using the wrong host for authorization and token API calls. The token endpoint URL is `{tenant}.api.identitynow.com`, while the authorize URL is `{tenant}.identitynow.com`.
|
||||||
The token endpoint URL is `{tenant}.api.identitynow.com`, while the authorize URL is `{tenant}.identitynow.com`.
|
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ pagination_label: Authorization
|
|||||||
sidebar_label: Authorization
|
sidebar_label: Authorization
|
||||||
sidebar_position: 3
|
sidebar_position: 3
|
||||||
sidebar_class_name: authorization
|
sidebar_class_name: authorization
|
||||||
keywords: ['authorization','scope','permission']
|
keywords: ['authorization', 'scope', 'permission']
|
||||||
description: Authorize your ISC API requests.
|
description: Authorize your ISC API requests.
|
||||||
slug: /api/authorization
|
slug: /api/authorization
|
||||||
tags: ['Authorization','Scopes','Permissions']
|
tags: ['Authorization', 'Scopes', 'Permissions']
|
||||||
---
|
---
|
||||||
|
|
||||||
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
|
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
|
||||||
@@ -41,7 +41,7 @@ sequenceDiagram
|
|||||||
|
|
||||||
## User Level Permissions
|
## User Level Permissions
|
||||||
|
|
||||||
When managing a user's access to the API, you must first assign the target user an appropriate [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html). It is important to choose the correct user level as it will place a boundary on which APIs a user can call, which also affects the areas and functions of the UI they have access to. For example, if a user is in charge of creating reports for auditing requirements, consider granting them the "Report Admin" user level.
|
When managing a user's access to the API, you must first assign the target user an appropriate [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html). It is important to choose the correct user level as it will place a boundary on which APIs a user can call, which also affects the areas and functions of the UI they have access to. For example, if a user is in charge of creating reports for auditing requirements, consider granting them the "Report Admin" user level.
|
||||||
|
|
||||||
User levels are typically granted through the UI, [following the procedures from this document](https://documentation.sailpoint.com/saas/help/common/users/grant_remove_user_levels.html).
|
User levels are typically granted through the UI, [following the procedures from this document](https://documentation.sailpoint.com/saas/help/common/users/grant_remove_user_levels.html).
|
||||||
|
|
||||||
@@ -51,26 +51,26 @@ There is an [API that can set an identity's user level](https://developer.sailpo
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
User levels act as the first line of defense by applying a rigid boundary around the APIs that a user can call. The next section introduces scopes, which allow users to apply granular controls on the APIs an access token can call.
|
User levels act as the first line of defense by applying a rigid boundary around the APIs that a user can call. The next section introduces scopes, which allow users to apply granular controls on the APIs an access token can call.
|
||||||
|
|
||||||
## Scopes
|
## Scopes
|
||||||
|
|
||||||
Scopes are granular permissions you can add to personal access tokens (PATs) to create tokens with the least privilege necessary to fulfill their functions. User levels place a broad border around the APIs a token has access to, while scopes can further limit the set of endpoints a token can call. Scopes allow an API user to have multiple tokens with different privileges that support unique use cases and software applications. Using scopes is beneficial to security - if a bad actor compromises any one of the tokens, the bad actor can only perform the limited set of operations defined by the token's scopes, significantly reducing the potential damage that can be done. Therefore, it is recommended that all users apply scopes to each PAT they create in order to reduce the impact of stolen credentials.
|
Scopes are granular permissions you can add to personal access tokens (PATs) to create tokens with the least privilege necessary to fulfill their functions. User levels place a broad border around the APIs a token has access to, while scopes can further limit the set of endpoints a token can call. Scopes allow an API user to have multiple tokens with different privileges that support unique use cases and software applications. Using scopes is beneficial to security - if a bad actor compromises any one of the tokens, the bad actor can only perform the limited set of operations defined by the token's scopes, significantly reducing the potential damage that can be done. Therefore, it is recommended that all users apply scopes to each PAT they create in order to reduce the impact of stolen credentials.
|
||||||
|
|
||||||
Scopes contain one or more rights, which are low level permissions that grant access to individual endpoints. This means that a single scope, like `idn:access-request:manage`, can grant access to multiple API endpoints. To determine which scopes a PAT needs, you must first identify which endpoints the PAT needs to invoke. Each endpoint's API specification indicates which scope is necessary to call the endpoint. You can use this approach to curate a list of scopes that must be applied to the credential to call the necessary endpoints. [Learn more about how to find an API's required scopes here](#identifying-necessary-authorization-for-an-endpoint).
|
Scopes contain one or more rights, which are low level permissions that grant access to individual endpoints. This means that a single scope, like `idn:access-request:manage`, can grant access to multiple API endpoints. To determine which scopes a PAT needs, you must first identify which endpoints the PAT needs to invoke. Each endpoint's API specification indicates which scope is necessary to call the endpoint. You can use this approach to curate a list of scopes that must be applied to the credential to call the necessary endpoints. [Learn more about how to find an API's required scopes here](#identifying-necessary-authorization-for-an-endpoint).
|
||||||
|
|
||||||
By default, each PAT has the scope `sp:scopes:default`, which is the least privileged scope. It only grants access to endpoints that require no authorization at all, such as [List Public Identities](https://developer.sailpoint.com/idn/api/v3/get-public-identities). Access to the endpoint may still be determined by the user's [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html).
|
By default, each PAT has the scope `sp:scopes:default`, which is the least privileged scope. It only grants access to endpoints that require no authorization at all, such as [List Public Identities](https://developer.sailpoint.com/idn/api/v3/get-public-identities). Access to the endpoint may still be determined by the user's [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html).
|
||||||
|
|
||||||
Alternatively, `sp:scopes:all` grants access to all the rights appropriate for the [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html). For example, a user with the **Admin** user level has access to all APIs, so `sp:scopes:all` grants **Admin** users access to all APIs. A user with the **Cert Admin** user level, however, has access to only a subset of APIs necessary to perform their role, most notably the certification APIs, so `sp:scopes:all` grants **Cert Admin** users access to only that subset of APIs.
|
Alternatively, `sp:scopes:all` grants access to all the rights appropriate for the [user level](https://documentation.sailpoint.com/saas/help/common/users/user_level_matrix.html). For example, a user with the **Admin** user level has access to all APIs, so `sp:scopes:all` grants **Admin** users access to all APIs. A user with the **Cert Admin** user level, however, has access to only a subset of APIs necessary to perform their role, most notably the certification APIs, so `sp:scopes:all` grants **Cert Admin** users access to only that subset of APIs.
|
||||||
|
|
||||||
Scopes are additive, which means the final right set is the intersection of all the rights granted by the scopes assigned to a PAT, excluding any rights that fall outside of the user level. Each scope added to an PAT builds up the credential's permission set, incrementally increasing access to the API. If a PAT has `sp:scopes:all` granted, then any additional scope is ignored because `sp:scopes:all` already contains the complete set of rights available to the user level.
|
Scopes are additive, which means the final right set is the intersection of all the rights granted by the scopes assigned to a PAT, excluding any rights that fall outside of the user level. Each scope added to an PAT builds up the credential's permission set, incrementally increasing access to the API. If a PAT has `sp:scopes:all` granted, then any additional scope is ignored because `sp:scopes:all` already contains the complete set of rights available to the user level.
|
||||||
|
|
||||||
:::tip
|
:::tip
|
||||||
|
|
||||||
If the API requirements for the personal access token exceed the scopes allowed by the user's assigned user level, then the following options may be considered.
|
If the API requirements for the personal access token exceed the scopes allowed by the user's assigned user level, then the following options may be considered.
|
||||||
|
|
||||||
- Re-evaluate the user's responsibilities compared to their user level. It is possible that their user level is no longer appropriate for the functions they need to perform, and a more permissive user level may be necessary.
|
- Re-evaluate the user's responsibilities compared to their user level. It is possible that their user level is no longer appropriate for the functions they need to perform, and a more permissive user level may be necessary.
|
||||||
- If the required access is a one-off need for a specific use case, then consider generating a PAT with the required scopes from a different user and sharing the credentials. This could be a dedicated service account designated for one-off applications. The downside of this approach is that it becomes more difficult to attribute an API call to a specific user, as the user now has a PAT that is not tied to their user account.
|
- If the required access is a one-off need for a specific use case, then consider generating a PAT with the required scopes from a different user and sharing the credentials. This could be a dedicated service account designated for one-off applications. The downside of this approach is that it becomes more difficult to attribute an API call to a specific user, as the user now has a PAT that is not tied to their user account.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ Each endpoint document specifies how to authorize with the endpoint in the **Aut
|
|||||||
- **flow**: One or more OAuth flows supported by the endpoint. A token only needs to be generated by one flow to be valid. Refer to [Authentication Details](./authentication.md#authentication-details) for more information about the available flows.
|
- **flow**: One or more OAuth flows supported by the endpoint. A token only needs to be generated by one flow to be valid. Refer to [Authentication Details](./authentication.md#authentication-details) for more information about the available flows.
|
||||||
- **scopes**: A list of scopes necessary to access the endpoint. A token only needs one of the scopes to authorize with the endpoint. When possible, choose the least privileged scope. Scopes ending in `read` can only retrieve data. Scopes ending in `manage` can retrieve, modify, and delete data.
|
- **scopes**: A list of scopes necessary to access the endpoint. A token only needs one of the scopes to authorize with the endpoint. When possible, choose the least privileged scope. Scopes ending in `read` can only retrieve data. Scopes ending in `manage` can retrieve, modify, and delete data.
|
||||||
|
|
||||||
You may also notice that many API descriptions will indicate the user level(s) required to call the API endpoint. In the screenshot above, the list access profiles endpoint requires the user to have one of the following user levels: ORG_ADMIN, ROLE_ADMIN, ROLE_SUBADMIN, SOURCE_ADMIN, or SOURCE_SUBADMIN. This means the PAT must have one of those user level **in addition to** the `sp:scopes:all` or `idn:access-profile:read` scope in order to call the endpoint.
|
You may also notice that many API descriptions will indicate the user level(s) required to call the API endpoint. In the screenshot above, the list access profiles endpoint requires the user to have one of the following user levels: ORG_ADMIN, ROLE_ADMIN, ROLE_SUBADMIN, SOURCE_ADMIN, or SOURCE_SUBADMIN. This means the PAT must have one of those user level **in addition to** the `sp:scopes:all` or `idn:access-profile:read` scope in order to call the endpoint.
|
||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
|
||||||
@@ -106,11 +106,8 @@ Request Body
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "Access Request and NELM Management",
|
"name": "Access Request and NELM Management",
|
||||||
"scope": [
|
"scope": ["idn:access-request:manage", "idn:nelm:manage"]
|
||||||
"idn:access-request:manage",
|
|
||||||
"idn:nelm:manage"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -118,24 +115,21 @@ This request produces the following response, indicating that the scopes were su
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id": "86286c0c456e4b03a8ccb1f892dd456d",
|
"id": "86286c0c456e4b03a8ccb1f892dd456d",
|
||||||
"name": "Access Request and NELM Management",
|
"name": "Access Request and NELM Management",
|
||||||
"secret": "********",
|
"secret": "********",
|
||||||
"scope": [
|
"scope": ["idn:access-request:manage", "idn:nelm:manage"],
|
||||||
"idn:access-request:manage",
|
"created": "2023-01-04T18:58:17.486584Z",
|
||||||
"idn:nelm:manage"
|
"owner": {
|
||||||
],
|
"name": "jane.doe",
|
||||||
"created": "2023-01-04T18:58:17.486584Z",
|
"id": "2c9180ab7624cbd7017642d8c8c81a73",
|
||||||
"owner": {
|
"type": "IDENTITY"
|
||||||
"name": "jane.doe",
|
}
|
||||||
"id": "2c9180ab7624cbd7017642d8c8c81a73",
|
|
||||||
"type": "IDENTITY"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
:::caution
|
:::caution
|
||||||
|
|
||||||
If you attempt to add a scope that is outside the permissions of the [target user's level](#user-level-permissions), the request will still succeed and include the invalid scope in the credentials. However, any token generated with these credentials will **not** include the rights of the invalid scope. This is not an issue when you apply scopes with the UI - the UI only shows scopes available to the current user.
|
If you attempt to add a scope that is outside the permissions of the [target user's level](#user-level-permissions), the request will still succeed and include the invalid scope in the credentials. However, any token generated with these credentials will **not** include the rights of the invalid scope. This is not an issue when you apply scopes with the UI - the UI only shows scopes available to the current user.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ sidebar_label: Getting Started
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: gettingStarted
|
sidebar_class_name: gettingStarted
|
||||||
keywords: ['getting started']
|
keywords: ['getting started']
|
||||||
description: Start using the ISC APIs.
|
description: Start using the ISC APIs.
|
||||||
slug: /api/getting-started
|
slug: /api/getting-started
|
||||||
tags: ['Getting Started']
|
tags: ['Getting Started']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This guide is intended to help you quickly make your first API call to SailPoint Identity Security Cloud and assumes an intermediate level of understanding of APIs. For beginners to APIs, we recommend you watch this presentation that covers the fundamentals of APIs with visual demonstrations of how to make an API call in SailPoint.
|
This guide is intended to help you quickly make your first API call to SailPoint Identity Security Cloud and assumes an intermediate level of understanding of APIs. For beginners to APIs, we recommend you watch this presentation that covers the fundamentals of APIs with visual demonstrations of how to make an API call in SailPoint.
|
||||||
|
|
||||||
<div class="text--center">
|
<div class="text--center">
|
||||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/YFRz8AcdWXg?si=9AvO6gMT1oCqYXAj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/YFRz8AcdWXg?si=9AvO6gMT1oCqYXAj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ sidebar_label: Identity Security Cloud API Specifications
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: iscSpecifications
|
sidebar_class_name: iscSpecifications
|
||||||
keywords: ['api', 'specifications']
|
keywords: ['api', 'specifications']
|
||||||
description: ISC API specifications.
|
description: ISC API specifications.
|
||||||
slug: /api
|
slug: /api
|
||||||
tags: ['API Specifications']
|
tags: ['API Specifications']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The Identity Security Cloud (ISC) APIs provide developers with a way to interact with the ISC platform and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
The Identity Security Cloud (ISC) APIs provide developers with a way to interact with the ISC platform and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
import DocCardList from '@theme/DocCardList';
|
import DocCardList from '@theme/DocCardList';
|
||||||
@@ -22,8 +22,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
|
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
To learn more about the ISC APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tags/c/isc/6/apis).
|
To learn more about the ISC APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tags/c/isc/6/apis).
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ slug: /api/nerm/authentication
|
|||||||
tags: ['Authentication']
|
tags: ['Authentication']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
NERM uses bearer tokens to allow customers to authenticate to NERM API endpoints. These tokens can be generated by following the instructions [here](https://documentation.sailpoint.com/ne-admin/help/setup/api.html).
|
NERM uses bearer tokens to allow customers to authenticate to NERM API endpoints. These tokens can be generated by following the instructions [here](https://documentation.sailpoint.com/ne-admin/help/setup/api.html).
|
||||||
@@ -20,5 +18,3 @@ NERM uses bearer tokens to allow customers to authenticate to NERM API endpoints
|
|||||||
## Example
|
## Example
|
||||||
|
|
||||||
To use your bearer token simply provide it in the header with the request like so: `Authorization: Bearer <token>`
|
To use your bearer token simply provide it in the header with the request like so: `Authorization: Bearer <token>`
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Use the following optional query parameters to achieve pagination:
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `limit` | Integer specifying the maximum number of records to return in a single API call. If it is not specified, a default limit is used. | `100` | Maxiumum of 500 for `api/profiles` |
|
| `limit` | Integer specifying the maximum number of records to return in a single API call. If it is not specified, a default limit is used. | `100` | Maxiumum of 500 for `api/profiles` |
|
||||||
| `offset` | Integer specifying the offset of the first result from the beginning of the collection. The **offset** value is record-based, not page-based, and the index starts at 0. For example, **offset=0** and **limit=20** returns records 0-19, but **offset=1** and **limit=20** returns records 1-20. | `0` | Between 0 and the last record index. |
|
| `offset` | Integer specifying the offset of the first result from the beginning of the collection. The **offset** value is record-based, not page-based, and the index starts at 0. For example, **offset=0** and **limit=20** returns records 0-19, but **offset=1** and **limit=20** returns records 1-20. | `0` | Between 0 and the last record index. |
|
||||||
| `order` | String specifying the ascending order in which the results should be returned, for example, **order=login** would return the users results in an ascending alphanumeric order| - | Limited to specific parameters |
|
| `order` | String specifying the ascending order in which the results should be returned, for example, **order=login** would return the users results in an ascending alphanumeric order | - | Limited to specific parameters |
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -39,11 +39,12 @@ Metadata can be added to a result to allow for progromatic approaches to fetchin
|
|||||||
|
|
||||||
| Name | Description | Default |
|
| Name | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `metadata` | Boolean that specifies wether or not to return a **_metadata** key with pagination information | false |
|
| `metadata` | Boolean that specifies wether or not to return a **\_metadata** key with pagination information | false |
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
- GET `/api/users?metadata=true`
|
- GET `/api/users?metadata=true`
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
@@ -61,6 +62,7 @@ Example:
|
|||||||
Resource attributes can be added to parameters to perform a basic match filter. Refer to each documented endpoints **Query Parameters** to identify what can be used.
|
Resource attributes can be added to parameters to perform a basic match filter. Refer to each documented endpoints **Query Parameters** to identify what can be used.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
- GET `/api/users?email=jim@acmeco.com`
|
- GET `/api/users?email=jim@acmeco.com`
|
||||||
|
|
||||||
## Advanced Profile Filtering
|
## Advanced Profile Filtering
|
||||||
@@ -115,12 +117,12 @@ There are 3 types of **condition_rules_attributes**
|
|||||||
This rule searches for profiles based on the status.
|
This rule searches for profiles based on the status.
|
||||||
|
|
||||||
| Key | Type | Description |
|
| Key | Type | Description |
|
||||||
|----------|------|-----------------------|
|
| --- | --- | --- |
|
||||||
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
||||||
| type | string **required** | The value must be 'ProfileStatusRule' |
|
| type | string **required** | The value must be 'ProfileStatusRule' |
|
||||||
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. <br></br>Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li></ul> |
|
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. <br></br>Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li></ul> |
|
||||||
| value | string **required** | This is the value used for comparison.0 <br></br>Available Values: <ul><li>Active</li><li>Inactive</li><li>Leave of absence</li><li>Terminated</li></ul> |
|
| value | string **required** | This is the value used for comparison.0 <br></br>Available Values: <ul><li>Active</li><li>Inactive</li><li>Leave of absence</li><li>Terminated</li></ul> |
|
||||||
| _destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
| \_destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -143,12 +145,12 @@ Example:
|
|||||||
This rule searches for profiles based on the id of the profile type.
|
This rule searches for profiles based on the id of the profile type.
|
||||||
|
|
||||||
| Key | Type | Description |
|
| Key | Type | Description |
|
||||||
|----------|------|-----------------------|
|
| --- | --- | --- |
|
||||||
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
||||||
| type | string **required** | The value must be 'ProfileTypeRule' |
|
| type | string **required** | The value must be 'ProfileTypeRule' |
|
||||||
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li></ul> |
|
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li></ul> |
|
||||||
| value | string **required** | This is the value used for comparison. This should be the ID of the profile type |
|
| value | string **required** | This is the value used for comparison. This should be the ID of the profile type |
|
||||||
| _destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
| \_destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -171,14 +173,14 @@ Example:
|
|||||||
This rule searches for profiles based on an attribute that profile has.
|
This rule searches for profiles based on an attribute that profile has.
|
||||||
|
|
||||||
| Key | Type | Description |
|
| Key | Type | Description |
|
||||||
|----------|------|-----------------------|
|
| --- | --- | --- |
|
||||||
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
| id | string | If you are updating an existing rule, include the ID of that rule, if you do not include an ID it will create a new condition rule |
|
||||||
| type | string **required** | The value must be 'ProfileAttributeRule' |
|
| type | string **required** | The value must be 'ProfileAttributeRule' |
|
||||||
| object_type | string **required** | The values must equal 'NeAttribute' |
|
| object_type | string **required** | The values must equal 'NeAttribute' |
|
||||||
| condition_object_id | string **required** | this is the id of the attribute you are searching against |
|
| condition_object_id | string **required** | this is the id of the attribute you are searching against |
|
||||||
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. <br></br>Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li><li>> (greater than)</li><li>< (less than)</li><li>start_with? (starts with)</li><li>end_with? (ends with)</li><li>include? (includes)</li></ul> Available date operators: <ul><li>before (before specific date)</li><li>after (after specific date)</li><li>> (more than X days before/after today)</li><li>< (less than X days before/after today)</li><li>== (equal to X days before/after today)</li></ul> |
|
| comparison_operator | string **required** | This is how the comparison is made for the attribute values. <br></br>Available basic operators: <ul><li>== (equals)</li><li>!= (not equal)</li><li>> (greater than)</li><li>< (less than)</li><li>start_with? (starts with)</li><li>end_with? (ends with)</li><li>include? (includes)</li></ul> Available date operators: <ul><li>before (before specific date)</li><li>after (after specific date)</li><li>> (more than X days before/after today)</li><li>< (less than X days before/after today)</li><li>== (equal to X days before/after today)</li></ul> |
|
||||||
| value | string **required** | This is the value used for comparison. <br></br>Value formatting: <ul><li>profile select attribute: ID of profile</li><li>profile search attribute: ID of profile</li><li>user select attribute: ID of user</li><li>user search attribute: ID of user</li><li>date attribute (before, after): correct date format for attribute</li><li>date attribute (>, <, ==): "X before" or "X after" where X is the number of days</li></ul> |
|
| value | string **required** | This is the value used for comparison. <br></br>Value formatting: <ul><li>profile select attribute: ID of profile</li><li>profile search attribute: ID of profile</li><li>user select attribute: ID of user</li><li>user search attribute: ID of user</li><li>date attribute (before, after): correct date format for attribute</li><li>date attribute (>, <, ==): "X before" or "X after" where X is the number of days</li></ul> |
|
||||||
| _destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
| \_destroy | boolean | Supplying this option with "true" will cause the condition to be destroyed |
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -196,4 +198,4 @@ Example:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ sidebar_label: NERM API Specifications
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: nermApiSpecifications
|
sidebar_class_name: nermApiSpecifications
|
||||||
keywords: ['api', 'specifications']
|
keywords: ['api', 'specifications']
|
||||||
description: NERM API specifications.
|
description: NERM API specifications.
|
||||||
slug: /api/nerm
|
slug: /api/nerm
|
||||||
tags: ['API Specifications']
|
tags: ['API Specifications']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
[Non-Employee Risk Management (NERM)](https://documentation.sailpoint.com/ne-admin/help/) is an add-on to Identity Security Cloud (ISC) that helps organizations track non-employees such as contractors, partners, and vendors, and their lifecycles within the organization.
|
[Non-Employee Risk Management (NERM)](https://documentation.sailpoint.com/ne-admin/help/) is an add-on to Identity Security Cloud (ISC) that helps organizations track non-employees such as contractors, partners, and vendors, and their lifecycles within the organization.
|
||||||
|
|
||||||
The Non-Employee Risk Management (NERM) APIs provide developers with a way to interact with the NERM add-on and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
The Non-Employee Risk Management (NERM) APIs provide developers with a way to interact with the NERM add-on and extend it. Developers can leverage these APIs to customize their platform experiences and build new solutions and integrations that meet their needs.
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
import DocCardList from '@theme/DocCardList';
|
import DocCardList from '@theme/DocCardList';
|
||||||
@@ -24,8 +24,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
|
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
To learn more about the NERM APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tag/nerm).
|
To learn more about the NERM APIs and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/tag/nerm).
|
||||||
|
|||||||
@@ -10,159 +10,145 @@ description: Send PATCH ISC API requests.
|
|||||||
tags: ['patch', 'guide']
|
tags: ['patch', 'guide']
|
||||||
---
|
---
|
||||||
|
|
||||||
## PATCH requests
|
## PATCH requests
|
||||||
|
|
||||||
You can use the Identity Security Cloud APIs to update existing resources. Many of the APIs offer multiple ways to do so:
|
You can use the Identity Security Cloud APIs to update existing resources. Many of the APIs offer multiple ways to do so:
|
||||||
|
|
||||||
- You can send a **PUT** request to replace the existing resource with a new one. For example, if you wanted to update one of John Doe's source accounts, you could use the [Put Account](https://developer.sailpoint.com/docs/api/v3/put-account) endpoint to replace John Doe's existing source account with a new one. This is a viable way to update a resource, but it requires you to update the entire resource each time.
|
- You can send a **PUT** request to replace the existing resource with a new one. For example, if you wanted to update one of John Doe's source accounts, you could use the [Put Account](https://developer.sailpoint.com/docs/api/v3/put-account) endpoint to replace John Doe's existing source account with a new one. This is a viable way to update a resource, but it requires you to update the entire resource each time.
|
||||||
|
|
||||||
- You can send a **PATCH** request to make a specific change to the resource. For example, if you wanted to update John Doe's account's associated `identityId` attribute, you could use the [Patch Account](https://developer.sailpoint.com/docs/api/v3/update-account) endpoint to replace his existing `identityId` with a new one, all without affecting any of the other source account details. This can be very helpful when you want to make specific updates to resources, but it requires some knowledge of the types of changes, or "operations", that are possible, the specific paths of the fields you want to update, and some understanding of the basic data types.
|
- You can send a **PATCH** request to make a specific change to the resource. For example, if you wanted to update John Doe's account's associated `identityId` attribute, you could use the [Patch Account](https://developer.sailpoint.com/docs/api/v3/update-account) endpoint to replace his existing `identityId` with a new one, all without affecting any of the other source account details. This can be very helpful when you want to make specific updates to resources, but it requires some knowledge of the types of changes, or "operations", that are possible, the specific paths of the fields you want to update, and some understanding of the basic data types.
|
||||||
|
|
||||||
This guide will focus on the partial update method, PATCH requests. Read this guide to learn how to start sending PATCH requests.
|
This guide will focus on the partial update method, PATCH requests. Read this guide to learn how to start sending PATCH requests.
|
||||||
|
|
||||||
## Get the resource ID
|
## Get the resource ID
|
||||||
|
|
||||||
To use PATCH to update a resource, you first need to know the resource ID.
|
To use PATCH to update a resource, you first need to know the resource ID.
|
||||||
|
|
||||||
Not all resource IDs are available in the Identity Security Cloud UI, so you may need to use the API to find the ID for the resource you want to update.
|
Not all resource IDs are available in the Identity Security Cloud UI, so you may need to use the API to find the ID for the resource you want to update.
|
||||||
|
|
||||||
For example, account IDs aren't avilable in the Identity Security Cloud UI. If you want to use the [Patch Account](https://developer.sailpoint.com/docs/api/v3/update-account) endpoint to make a change to a specific account, you first need to find out the account's ID.
|
For example, account IDs aren't avilable in the Identity Security Cloud UI. If you want to use the [Patch Account](https://developer.sailpoint.com/docs/api/v3/update-account) endpoint to make a change to a specific account, you first need to find out the account's ID.
|
||||||
|
|
||||||
You can use the [List Accounts](https://developer.sailpoint.com/docs/api/v3/list-accounts) endpoint to view all the accounts in your tenant, along with their details, such as their identities. You can find your account and its ID in this list.
|
You can use the [List Accounts](https://developer.sailpoint.com/docs/api/v3/list-accounts) endpoint to view all the accounts in your tenant, along with their details, such as their identities. You can find your account and its ID in this list.
|
||||||
|
|
||||||
## Get the resource details
|
## Get the resource details
|
||||||
|
|
||||||
Once you know the resource ID, you can use a GET request to get that resource's details. To successfully use a PATCH request to make changes to a resource, you need to know which paths you can update, what values they have, and the structure of those paths.
|
Once you know the resource ID, you can use a GET request to get that resource's details. To successfully use a PATCH request to make changes to a resource, you need to know which paths you can update, what values they have, and the structure of those paths.
|
||||||
|
|
||||||
For example, once you know the ID for the source you want to update with a PATCH request, you can use the [Get Source by ID](https://developer.sailpoint.com/docs/api/v3/get-source) endpoint to view only that source and its details.
|
For example, once you know the ID for the source you want to update with a PATCH request, you can use the [Get Source by ID](https://developer.sailpoint.com/docs/api/v3/get-source) endpoint to view only that source and its details.
|
||||||
|
|
||||||
In this example, the API returns a source, "ubuntu", along with all its details. This JSON response shows the resource's structure and its different paths:
|
In this example, the API returns a source, "ubuntu", along with all its details. This JSON response shows the resource's structure and its different paths:
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Example Source Details</summary>
|
<summary>Example Source Details</summary>
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
||||||
{
|
{
|
||||||
"description": "ubuntu",
|
"description": "ubuntu",
|
||||||
"owner": {
|
"owner": {
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"id": "2c91808475b4334b0175e1e005006401",
|
"id": "2c91808475b4334b0175e1e005006401",
|
||||||
"name": "SailPoint Services"
|
"name": "SailPoint Services"
|
||||||
|
},
|
||||||
|
"cluster": null,
|
||||||
|
"accountCorrelationConfig": null,
|
||||||
|
"accountCorrelationRule": null,
|
||||||
|
"managerCorrelationMapping": null,
|
||||||
|
"managerCorrelationRule": null,
|
||||||
|
"beforeProvisioningRule": null,
|
||||||
|
"schemas": [
|
||||||
|
{
|
||||||
|
"type": "CONNECTOR_SCHEMA",
|
||||||
|
"id": "2c91808c771b686101772a91dbd877ab",
|
||||||
|
"name": "account"
|
||||||
},
|
},
|
||||||
"cluster": null,
|
{
|
||||||
"accountCorrelationConfig": null,
|
"type": "CONNECTOR_SCHEMA",
|
||||||
"accountCorrelationRule": null,
|
"id": "2c91808c771b686101772a91dbd877ac",
|
||||||
"managerCorrelationMapping": null,
|
"name": "group"
|
||||||
"managerCorrelationRule": null,
|
}
|
||||||
"beforeProvisioningRule": null,
|
],
|
||||||
"schemas": [
|
"passwordPolicies": null,
|
||||||
{
|
"features": ["NO_RANDOM_ACCESS", "DISCOVER_SCHEMA", "DIRECT_PERMISSIONS"],
|
||||||
"type": "CONNECTOR_SCHEMA",
|
"type": "DelimitedFile",
|
||||||
"id": "2c91808c771b686101772a91dbd877ab",
|
"connector": "delimited-file-angularsc",
|
||||||
"name": "account"
|
"connectorClass": "sailpoint.connector.DelimitedFileConnector",
|
||||||
},
|
"connectorAttributes": {
|
||||||
{
|
"mergeColumns": ["groups"],
|
||||||
"type": "CONNECTOR_SCHEMA",
|
"group.mergeRows": true,
|
||||||
"id": "2c91808c771b686101772a91dbd877ac",
|
"group.delimiter": ",",
|
||||||
"name": "group"
|
"mergeRows": true,
|
||||||
}
|
"group.filetransport": "local",
|
||||||
],
|
"partitionMode": "disabled",
|
||||||
"passwordPolicies": null,
|
|
||||||
"features": [
|
|
||||||
"NO_RANDOM_ACCESS",
|
|
||||||
"DISCOVER_SCHEMA",
|
|
||||||
"DIRECT_PERMISSIONS"
|
|
||||||
],
|
|
||||||
"type": "DelimitedFile",
|
|
||||||
"connector": "delimited-file-angularsc",
|
|
||||||
"connectorClass": "sailpoint.connector.DelimitedFileConnector",
|
|
||||||
"connectorAttributes": {
|
|
||||||
"mergeColumns": [
|
|
||||||
"groups"
|
|
||||||
],
|
|
||||||
"group.mergeRows": true,
|
|
||||||
"group.delimiter": ",",
|
|
||||||
"mergeRows": true,
|
|
||||||
"group.filetransport": "local",
|
|
||||||
"partitionMode": "disabled",
|
|
||||||
"connectionType": "file",
|
|
||||||
"group.host": "local",
|
|
||||||
"group.indexColumn": "id",
|
|
||||||
"file": "/tmp/source-account-2c91808c771b686101772a91dbd877aa3299228430527475607.csv",
|
|
||||||
"delimiter": ",",
|
|
||||||
"deltaAggregation": null,
|
|
||||||
"host": "local",
|
|
||||||
"cloudExternalId": "23012",
|
|
||||||
"group.indexColumns": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"cloudIdentityProfileName": null,
|
|
||||||
"group.mergeColumns": [
|
|
||||||
"entitlements",
|
|
||||||
"groups",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"hasHeader": true,
|
|
||||||
"filterEmptyRecords": true,
|
|
||||||
"oauth_body_attrs_to_exclude": "client_secret,client_id",
|
|
||||||
"filetransport": "local",
|
|
||||||
"idnPreviousCorrelationConfig": null,
|
|
||||||
"deleteThresholdPercentage": 10,
|
|
||||||
"group.filterEmptyRecords": true,
|
|
||||||
"group.hasHeader": true,
|
|
||||||
"group.partitionMode": "disabled",
|
|
||||||
"cloudAuthoritativeSourcePrecedence": null,
|
|
||||||
"formPath": null,
|
|
||||||
"group.columnNames": [
|
|
||||||
"id",
|
|
||||||
"name",
|
|
||||||
"displayName",
|
|
||||||
"created",
|
|
||||||
"description",
|
|
||||||
"modified",
|
|
||||||
"entitlements",
|
|
||||||
"groups",
|
|
||||||
"permissions"
|
|
||||||
],
|
|
||||||
"templateApplication": "DelimitedFile Template",
|
|
||||||
"group.file": "/var/lib/identityiq_workspace/27c92c24-8681-4574-9453-5c56370b3fc9-groups.csv",
|
|
||||||
"indexColumn": "id",
|
|
||||||
"healthy": false,
|
|
||||||
"cloudDisplayName": "Ubuntu",
|
|
||||||
"connectorName": "Delimited File",
|
|
||||||
"beforeProvisioningRule": null,
|
|
||||||
"cloudOriginalApplicationType": "Delimited File",
|
|
||||||
"since": "2021-01-22T14:48:58.072Z",
|
|
||||||
"status": "SOURCE_STATE_ERROR_ACCOUNT_FILE_IMPORT"
|
|
||||||
},
|
|
||||||
"deleteThreshold": 10,
|
|
||||||
"authoritative": false,
|
|
||||||
"healthy": false,
|
|
||||||
"status": "SOURCE_STATE_ERROR_ACCOUNT_FILE_IMPORT",
|
|
||||||
"since": "2021-01-22T14:48:58.072Z",
|
|
||||||
"connectorId": "delimited-file",
|
|
||||||
"connectorName": "Delimited File",
|
|
||||||
"connectionType": "file",
|
"connectionType": "file",
|
||||||
"connectorImplementationId": "delimited-file",
|
"group.host": "local",
|
||||||
"managementWorkgroup": null,
|
"group.indexColumn": "id",
|
||||||
"id": "2c91808c771b686101772a91dbd877aa",
|
"file": "/tmp/source-account-2c91808c771b686101772a91dbd877aa3299228430527475607.csv",
|
||||||
"name": "Ubuntu",
|
"delimiter": ",",
|
||||||
"created": "2021-01-22T14:48:58.072Z",
|
"deltaAggregation": null,
|
||||||
"modified": "2023-06-30T13:39:07.456Z"
|
"host": "local",
|
||||||
|
"cloudExternalId": "23012",
|
||||||
|
"group.indexColumns": ["id"],
|
||||||
|
"cloudIdentityProfileName": null,
|
||||||
|
"group.mergeColumns": ["entitlements", "groups", "permissions"],
|
||||||
|
"hasHeader": true,
|
||||||
|
"filterEmptyRecords": true,
|
||||||
|
"oauth_body_attrs_to_exclude": "client_secret,client_id",
|
||||||
|
"filetransport": "local",
|
||||||
|
"idnPreviousCorrelationConfig": null,
|
||||||
|
"deleteThresholdPercentage": 10,
|
||||||
|
"group.filterEmptyRecords": true,
|
||||||
|
"group.hasHeader": true,
|
||||||
|
"group.partitionMode": "disabled",
|
||||||
|
"cloudAuthoritativeSourcePrecedence": null,
|
||||||
|
"formPath": null,
|
||||||
|
"group.columnNames": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"displayName",
|
||||||
|
"created",
|
||||||
|
"description",
|
||||||
|
"modified",
|
||||||
|
"entitlements",
|
||||||
|
"groups",
|
||||||
|
"permissions"
|
||||||
|
],
|
||||||
|
"templateApplication": "DelimitedFile Template",
|
||||||
|
"group.file": "/var/lib/identityiq_workspace/27c92c24-8681-4574-9453-5c56370b3fc9-groups.csv",
|
||||||
|
"indexColumn": "id",
|
||||||
|
"healthy": false,
|
||||||
|
"cloudDisplayName": "Ubuntu",
|
||||||
|
"connectorName": "Delimited File",
|
||||||
|
"beforeProvisioningRule": null,
|
||||||
|
"cloudOriginalApplicationType": "Delimited File",
|
||||||
|
"since": "2021-01-22T14:48:58.072Z",
|
||||||
|
"status": "SOURCE_STATE_ERROR_ACCOUNT_FILE_IMPORT"
|
||||||
|
},
|
||||||
|
"deleteThreshold": 10,
|
||||||
|
"authoritative": false,
|
||||||
|
"healthy": false,
|
||||||
|
"status": "SOURCE_STATE_ERROR_ACCOUNT_FILE_IMPORT",
|
||||||
|
"since": "2021-01-22T14:48:58.072Z",
|
||||||
|
"connectorId": "delimited-file",
|
||||||
|
"connectorName": "Delimited File",
|
||||||
|
"connectionType": "file",
|
||||||
|
"connectorImplementationId": "delimited-file",
|
||||||
|
"managementWorkgroup": null,
|
||||||
|
"id": "2c91808c771b686101772a91dbd877aa",
|
||||||
|
"name": "Ubuntu",
|
||||||
|
"created": "2021-01-22T14:48:58.072Z",
|
||||||
|
"modified": "2023-06-30T13:39:07.456Z"
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## PATCH request structure
|
## PATCH request structure
|
||||||
|
|
||||||
A PATCH request involves sending a JSON PATCH document that represents an array of objects. Each object represents a single operation to be applied to the target resource.
|
A PATCH request involves sending a JSON PATCH document that represents an array of objects. Each object represents a single operation to be applied to the target resource.
|
||||||
|
|
||||||
PATCH requests all share the same essential structure. A PATCH request must include an object that specifies exactly one operation to apply to update the resource, as well as exactly one path that represents the target location where the operation is applied.
|
PATCH requests all share the same essential structure. A PATCH request must include an object that specifies exactly one operation to apply to update the resource, as well as exactly one path that represents the target location where the operation is applied.
|
||||||
|
|
||||||
This example request has the basic PATCH structure:
|
This example request has the basic PATCH structure:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
@@ -176,31 +162,29 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
"value": "new description"
|
"value": "new description"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This example request uses a "replace" operation to replace the source's existing description with a new value, "new description". This example shows the parts involved in sending a PATCH request. You must specify an operation to apply to the target resource, a path to apply the operation to, and the change you want to make, often in the form of a value or a "from" location for "copy" and "move" operations.
|
This example request uses a "replace" operation to replace the source's existing description with a new value, "new description". This example shows the parts involved in sending a PATCH request. You must specify an operation to apply to the target resource, a path to apply the operation to, and the change you want to make, often in the form of a value or a "from" location for "copy" and "move" operations.
|
||||||
|
|
||||||
You can find this example in the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) specification. The API specifications have examples on the right side of the page that you can copy and use to get started. You can tab between the different examples to see a variety of pre-built requests you can use.
|
You can find this example in the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) specification. The API specifications have examples on the right side of the page that you can copy and use to get started. You can tab between the different examples to see a variety of pre-built requests you can use.
|
||||||
|
|
||||||
A PATCH request can be more complex as well - the values can be simple or vast and detailed. You can use a PATCH request to apply multiple operations, with a path for each, or you can apply the same type of operation to multiple paths. The PATCH request will always have the same essential structure though.
|
A PATCH request can be more complex as well - the values can be simple or vast and detailed. You can use a PATCH request to apply multiple operations, with a path for each, or you can apply the same type of operation to multiple paths. The PATCH request will always have the same essential structure though.
|
||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
The ordering of members in JSON objects doesn't affect the response. These examples all specify the operation first, but you would get the same response if you specified the members in any other order.
|
The ordering of members in JSON objects doesn't affect the response. These examples all specify the operation first, but you would get the same response if you specified the members in any other order.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
You can specify a single operation, or you can specify multiple. If you are using multiple operations in one PATCH request, each operation must include its own path.
|
You can specify a single operation, or you can specify multiple. If you are using multiple operations in one PATCH request, each operation must include its own path.
|
||||||
|
|
||||||
This example request applies "replace" and "add" ops to different paths:
|
This example request applies "replace" and "add" ops to different paths:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "replace",
|
"op": "replace",
|
||||||
@@ -213,116 +197,108 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
"value": "!( id.contains( \"m\" ) ) || !( id.contains( \"d\" ) )"
|
"value": "!( id.contains( \"m\" ) ) || !( id.contains( \"d\" ) )"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This example request uses a "replace" to update the source's description and an "add" to add a filter string to the source's connector.
|
This example request uses a "replace" to update the source's description and an "add" to add a filter string to the source's connector.
|
||||||
|
|
||||||
## Specify an operation
|
## Specify an operation
|
||||||
|
|
||||||
Once you know the ID of the resource you want to update and you have the resource's details, you can start writing your PATCH request.
|
Once you know the ID of the resource you want to update and you have the resource's details, you can start writing your PATCH request.
|
||||||
|
|
||||||
The first step is to specify an operation to apply to the target resource.
|
The first step is to specify an operation to apply to the target resource.
|
||||||
|
|
||||||
Operation objects must have exactly one "op" member, whose value indicates the operation to perform.
|
Operation objects must have exactly one "op" member, whose value indicates the operation to perform.
|
||||||
|
|
||||||
These are the available PATCH operations:
|
These are the available PATCH operations:
|
||||||
|
|
||||||
- [Add](#add)
|
- [Add](#add)
|
||||||
- [Remove](#remove)
|
- [Remove](#remove)
|
||||||
- [Replace](#replace)
|
- [Replace](#replace)
|
||||||
- [Move](#move)
|
- [Move](#move)
|
||||||
- [Copy](#copy)
|
- [Copy](#copy)
|
||||||
- [Test](#test)
|
- [Test](#test)
|
||||||
|
|
||||||
### Add
|
### Add
|
||||||
|
|
||||||
The "add" operation adds a value to the target location. For more information about the "add" operation and how it behaves in different scenarios, refer to the [JSON PATCH documentation](https://datatracker.ietf.org/doc/html/rfc6902).
|
The "add" operation adds a value to the target location. For more information about the "add" operation and how it behaves in different scenarios, refer to the [JSON PATCH documentation](https://datatracker.ietf.org/doc/html/rfc6902).
|
||||||
|
|
||||||
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to add a new "office" attribute to the end of a source schema's array of attributes:
|
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to add a new "office" attribute to the end of a source schema's array of attributes:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "add",
|
"op": "add",
|
||||||
"path": "/attributes/-",
|
"path": "/attributes/-",
|
||||||
"value":
|
"value": {
|
||||||
{
|
"name": "office",
|
||||||
"name": "office",
|
"type": "STRING",
|
||||||
"type": "STRING",
|
"schema": null,
|
||||||
"schema": null,
|
"description": "Office Location",
|
||||||
"description": "Office Location",
|
"isMulti": false,
|
||||||
"isMulti": false,
|
"isEntitlement": false,
|
||||||
"isEntitlement": false,
|
|
||||||
"isGroup": false
|
"isGroup": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
If you are adding a new value to an array of values, you can specify the position within the array where you want to add the new value. In this example, using the "-" expression at the end of the path specifies that the new attribute will be added to the end of the array of attributes.
|
If you are adding a new value to an array of values, you can specify the position within the array where you want to add the new value. In this example, using the "-" expression at the end of the path specifies that the new attribute will be added to the end of the array of attributes.
|
||||||
|
|
||||||
You can use "0" to add a value to the beginning of the array. You can use "1" to add a value to the second positon, and so on. Using "-" adds the value to the end of the array.
|
You can use "0" to add a value to the beginning of the array. You can use "1" to add a value to the second positon, and so on. Using "-" adds the value to the end of the array.
|
||||||
|
|
||||||
### Remove
|
### Remove
|
||||||
|
|
||||||
The "remove" operation removes a value from the target location. The target location must exist for the operation to be successful.
|
The "remove" operation removes a value from the target location. The target location must exist for the operation to be successful.
|
||||||
|
|
||||||
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to remove an existing filter string from a source's connector:
|
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to remove an existing filter string from a source's connector:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "remove",
|
"op": "remove",
|
||||||
"path": "/connectorAttributes/filterString"
|
"path": "/connectorAttributes/filterString"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
In this example, the PATCH request is removing a connector's string filter. If there is no string filter to remove, the request will fail and you will receive an error.
|
In this example, the PATCH request is removing a connector's string filter. If there is no string filter to remove, the request will fail and you will receive an error.
|
||||||
|
|
||||||
Because there is only one value for the path, the request removes that value.
|
Because there is only one value for the path, the request removes that value.
|
||||||
|
|
||||||
If there is an array of values, you must specify the position within the array to remove that value.
|
If there is an array of values, you must specify the position within the array to remove that value.
|
||||||
|
|
||||||
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to remove the first feature from a source's list of features.
|
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to remove the first feature from a source's list of features.
|
||||||
|
|
||||||
The source has three features, "ENABLE", "PROVISIONING", AND "UNLOCK".
|
The source has three features, "ENABLE", "PROVISIONING", AND "UNLOCK".
|
||||||
|
|
||||||
This request will remove the the first value from the list, "ENABLE".
|
This request will remove the the first value from the list, "ENABLE".
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "remove",
|
"op": "remove",
|
||||||
"path": "/features/0"
|
"path": "/features/0"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Replace
|
### Replace
|
||||||
|
|
||||||
The "replace" operation replaces the value at the target location with a new value. The operation object must contain a "value" member whose content specifies the replacement value, and the target location must exist for the operation to be successful. This operation is the equivalent of a "remove" followed by an "add".
|
The "replace" operation replaces the value at the target location with a new value. The operation object must contain a "value" member whose content specifies the replacement value, and the target location must exist for the operation to be successful. This operation is the equivalent of a "remove" followed by an "add".
|
||||||
|
|
||||||
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to replace a source's existing features with new ones:
|
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to replace a source's existing features with new ones:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "replace",
|
"op": "replace",
|
||||||
"path": "/features",
|
"path": "/features",
|
||||||
"value":
|
"value": ["PASSWORD", "PROVISIONING", "ENABLE", "AUTHENTICATE"]
|
||||||
[
|
|
||||||
"PASSWORD",
|
|
||||||
"PROVISIONING",
|
|
||||||
"ENABLE",
|
|
||||||
"AUTHENTICATE"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also replace a value within an array. This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to replace the first value in the array with the specified value:
|
You can also replace a value within an array. This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to replace the first value in the array with the specified value:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
@@ -334,71 +310,65 @@ You can also replace a value within an array. This example uses the [Patch Sourc
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
This request removes the first feature ("PASSWORD") in the list and adds the "CURRENT_PASSWORD" value in its place.
|
This request removes the first feature ("PASSWORD") in the list and adds the "CURRENT_PASSWORD" value in its place.
|
||||||
|
|
||||||
### Move
|
### Move
|
||||||
|
|
||||||
The "move" operation removes the operation from a specified location and adds it to the target location. This operation object must contain a "from" member whose content specifies the location to remove the value from, and the "from" location must exist for the operation to be successful.
|
The "move" operation removes the operation from a specified location and adds it to the target location. This operation object must contain a "from" member whose content specifies the location to remove the value from, and the "from" location must exist for the operation to be successful.
|
||||||
|
|
||||||
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to move an attribute from the beginning to the end of the schema's array of attributes:
|
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to move an attribute from the beginning to the end of the schema's array of attributes:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "move",
|
"op": "move",
|
||||||
"from": "/attributes/0",
|
"from": "/attributes/0",
|
||||||
"path": "/attributes/-"
|
"path": "/attributes/-"
|
||||||
}
|
}
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Copy
|
|
||||||
|
|
||||||
The "copy" operation copies the value from a specified location to the target location. The operation object must contain a "from" member whose content specifies the location to copy the value from, and the "from" location must exist for the operation to be successful.
|
|
||||||
|
|
||||||
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to copies an attribute from the beginning and duplicates it at the end of the schema's array of attributes:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"op": "copy",
|
|
||||||
"from": "/attributes/0",
|
|
||||||
"path": "/attributes/-"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Test
|
|
||||||
|
|
||||||
The "test" operation is unique in that it does not apply changes to the resource. The "test" operation tests that a value at the target location is equal to a specified value. The operation object must contain a "value" member whose content specifies the value to be compared to the target location's value, and the values must be equal for the operation to be successful. For more information about what "equal" means for different JSON types, refer [here](https://datatracker.ietf.org/doc/html/rfc6902#section-4.6).
|
|
||||||
|
|
||||||
The "test" operation allows you to check that a resource has the values you expect it to have, and then you can make changes to those values from there with another PATCH request.
|
|
||||||
|
|
||||||
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to test a source's existing features to make sure they match the specified values.:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"op": "test",
|
|
||||||
"path": "/features",
|
|
||||||
"value":
|
|
||||||
[
|
|
||||||
"PASSWORD",
|
|
||||||
"PROVISIONING",
|
|
||||||
"ENABLE",
|
|
||||||
"AUTHENTICATE"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Specify a path
|
### Copy
|
||||||
|
|
||||||
Once you have specified the operation you want to apply to the target resource, you must specify the path, the JSON Pointer for the target location that you want to apply the operation to.
|
The "copy" operation copies the value from a specified location to the target location. The operation object must contain a "from" member whose content specifies the location to copy the value from, and the "from" location must exist for the operation to be successful.
|
||||||
|
|
||||||
To send a PATCH request, you must know the path where you want to make the change. This is why it's important to get the resource's details so that you can see all the resource's available paths where you can make changes.
|
This example uses the [Patch Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to copies an attribute from the beginning and duplicates it at the end of the schema's array of attributes:
|
||||||
|
|
||||||
For example, this snippet from the beginning of the earlier source details example lists many of the source's top-level paths:
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op": "copy",
|
||||||
|
"from": "/attributes/0",
|
||||||
|
"path": "/attributes/-"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test
|
||||||
|
|
||||||
|
The "test" operation is unique in that it does not apply changes to the resource. The "test" operation tests that a value at the target location is equal to a specified value. The operation object must contain a "value" member whose content specifies the value to be compared to the target location's value, and the values must be equal for the operation to be successful. For more information about what "equal" means for different JSON types, refer [here](https://datatracker.ietf.org/doc/html/rfc6902#section-4.6).
|
||||||
|
|
||||||
|
The "test" operation allows you to check that a resource has the values you expect it to have, and then you can make changes to those values from there with another PATCH request.
|
||||||
|
|
||||||
|
This example uses the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) endpoint to test a source's existing features to make sure they match the specified values.:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"op": "test",
|
||||||
|
"path": "/features",
|
||||||
|
"value": ["PASSWORD", "PROVISIONING", "ENABLE", "AUTHENTICATE"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Specify a path
|
||||||
|
|
||||||
|
Once you have specified the operation you want to apply to the target resource, you must specify the path, the JSON Pointer for the target location that you want to apply the operation to.
|
||||||
|
|
||||||
|
To send a PATCH request, you must know the path where you want to make the change. This is why it's important to get the resource's details so that you can see all the resource's available paths where you can make changes.
|
||||||
|
|
||||||
|
For example, this snippet from the beginning of the earlier source details example lists many of the source's top-level paths:
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Example Source Paths</summary>
|
<summary>Example Source Paths</summary>
|
||||||
@@ -439,7 +409,7 @@ For example, this snippet from the beginning of the earlier source details examp
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
You can send PATCH requests to make changes to some of these paths, like editing the source's description with this PATCH request from earlier:
|
You can send PATCH requests to make changes to some of these paths, like editing the source's description with this PATCH request from earlier:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
@@ -455,9 +425,9 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
However, you cannot make changes to all paths. Use the API specifications for the PATCH endpoint you want to use to find out which paths you can make changes to. The API specifications will list the paths, or fields, that are immutable, if there are any. For example, the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) specification lists paths like `id` and `type` as being immutable. Trying to use modify these paths results in a 400 error.
|
However, you cannot make changes to all paths. Use the API specifications for the PATCH endpoint you want to use to find out which paths you can make changes to. The API specifications will list the paths, or fields, that are immutable, if there are any. For example, the [Patch Source](https://developer.sailpoint.com/docs/api/v3/update-source) specification lists paths like `id` and `type` as being immutable. Trying to use modify these paths results in a 400 error.
|
||||||
|
|
||||||
The paths are often nested within other paths, like within the "connectorAttributes" path from the earlier example source's details:
|
The paths are often nested within other paths, like within the "connectorAttributes" path from the earlier example source's details:
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Example Source Connector Attributes</summary>
|
<summary>Example Source Connector Attributes</summary>
|
||||||
@@ -527,7 +497,7 @@ The paths are often nested within other paths, like within the "connectorAttribu
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
You can send a PATCH request to make changes to paths within the "connectorAttributes" path itself. This example request removes the "filterString" path and its value.
|
You can send a PATCH request to make changes to paths within the "connectorAttributes" path itself. This example request removes the "filterString" path and its value.
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
@@ -543,19 +513,19 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
This request specifies the top-level path, "connectorAttributes", following it with the path where the value is going to be removed from, "filterString".
|
This request specifies the top-level path, "connectorAttributes", following it with the path where the value is going to be removed from, "filterString".
|
||||||
|
|
||||||
The request will only remove a filter string matching the one specified, so any other filter strings or connector attributes will be unaffected.
|
The request will only remove a filter string matching the one specified, so any other filter strings or connector attributes will be unaffected.
|
||||||
|
|
||||||
If there is no value matching the filter string specified by the PATCH request, the request will fail and you will receive an error.
|
If there is no value matching the filter string specified by the PATCH request, the request will fail and you will receive an error.
|
||||||
|
|
||||||
## Specify a value
|
## Specify a value
|
||||||
|
|
||||||
For many of the operations, once you have specified the operation you want to apply and the path you want to apply it to, you need to specify the value you want to send with the request. The value you specify must fit the path's data type.
|
For many of the operations, once you have specified the operation you want to apply and the path you want to apply it to, you need to specify the value you want to send with the request. The value you specify must fit the path's data type.
|
||||||
|
|
||||||
The operations that don't require a value are the "copy" and "move" operations. Those operations instead use a "from" to represent the location they are copying or moving the data from. Refer to the [Specify a From](#specify-a-from) section for more information about how to use "from" with your "copy" and "move" operations.
|
The operations that don't require a value are the "copy" and "move" operations. Those operations instead use a "from" to represent the location they are copying or moving the data from. Refer to the [Specify a From](#specify-a-from) section for more information about how to use "from" with your "copy" and "move" operations.
|
||||||
|
|
||||||
You can specify a single simple value for an operation. In this example from earlier, the PATCH request replaces the source's description:
|
You can specify a single simple value for an operation. In this example from earlier, the PATCH request replaces the source's description:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
@@ -571,7 +541,7 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also specify multiple values for an operation to be applied to, as long as they all affect the same path. For example, this PATCH request replaces the source's current features with a number of new ones:
|
You can also specify multiple values for an operation to be applied to, as long as they all affect the same path. For example, this PATCH request replaces the source's current features with a number of new ones:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
||||||
@@ -582,17 +552,12 @@ PATCH https://{tenant}.api.identitynow.com/v3/sources/:id
|
|||||||
{
|
{
|
||||||
"op": "replace",
|
"op": "replace",
|
||||||
"path": "/features",
|
"path": "/features",
|
||||||
"value": [
|
"value": ["PASSWORD", "PROVISIONING", "ENABLE", "AUTHENTICATE"]
|
||||||
"PASSWORD",
|
|
||||||
"PROVISIONING",
|
|
||||||
"ENABLE",
|
|
||||||
"AUTHENTICATE"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
A value can also be an object that contains other values within it. For example, this PATCH request adds a new "location" attribute to the end of the source schema's array of attributes:
|
A value can also be an object that contains other values within it. For example, this PATCH request adds a new "location" attribute to the end of the source schema's array of attributes:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com//v3/sources/:sourceId/schemas/:schemaId
|
PATCH https://{tenant}.api.identitynow.com//v3/sources/:sourceId/schemas/:schemaId
|
||||||
@@ -616,50 +581,48 @@ PATCH https://{tenant}.api.identitynow.com//v3/sources/:sourceId/schemas/:schema
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
This request uses the [PATCH Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to add a new attribute, along with its details, to the end of the array of a source's schema's attributes.
|
This request uses the [PATCH Source Schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to add a new attribute, along with its details, to the end of the array of a source's schema's attributes.
|
||||||
|
|
||||||
This example uses the "-" after the path to indicate that the value will be added to the end of the array. When you are adding a new value to an array of values, you can specify the position within the array where you want to add the new value. In this example, using the "-" expression at the end of the path specifies that the new attribute will be added to the end of the array of attributes.
|
This example uses the "-" after the path to indicate that the value will be added to the end of the array. When you are adding a new value to an array of values, you can specify the position within the array where you want to add the new value. In this example, using the "-" expression at the end of the path specifies that the new attribute will be added to the end of the array of attributes.
|
||||||
|
|
||||||
You can use "0" to add a value to the beginning of the array. You can use "1" to add a value to the second positon, and so on. Using "-" adds the value to the end of the array.
|
You can use "0" to add a value to the beginning of the array. You can use "1" to add a value to the second positon, and so on. Using "-" adds the value to the end of the array.
|
||||||
|
|
||||||
## Specify a from
|
## Specify a from
|
||||||
|
|
||||||
The "move" and "copy" operations allow you to remove or copy information from one path and add it to another path without your needing to specify the value, which could be an extensive array of information. To use the "move" and "copy" operations, you must specify a "from", a JSON Pointer representing the location you are moving or copying the value from.
|
The "move" and "copy" operations allow you to remove or copy information from one path and add it to another path without your needing to specify the value, which could be an extensive array of information. To use the "move" and "copy" operations, you must specify a "from", a JSON Pointer representing the location you are moving or copying the value from.
|
||||||
|
|
||||||
This example request uses the [PATCH Source schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to move an attribute, along with its details, from the beginning to the end of a source schema's array of attributes:
|
This example request uses the [PATCH Source schema](https://developer.sailpoint.com/docs/api/v3/update-source-schema) endpoint to move an attribute, along with its details, from the beginning to the end of a source schema's array of attributes:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
PATCH https://{tenant}.api.identitynow.com//v3/sources/:sourceId/schemas/:schemaId
|
PATCH https://{tenant}.api.identitynow.com//v3/sources/:sourceId/schemas/:schemaId
|
||||||
```
|
```
|
||||||
|
|
||||||
```json
|
```json
|
||||||
|
[
|
||||||
[
|
|
||||||
{
|
{
|
||||||
"op": "move",
|
"op": "move",
|
||||||
"from": "/attributes/0",
|
"from": "/attributes/0",
|
||||||
"path": "/attributes/-"
|
"path": "/attributes/-"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
```
|
||||||
|
|
||||||
```
|
Instead of having to specify the value yourself, which could be an extensive array of information, you can use the "move" operation to move everything from one path to another.
|
||||||
|
|
||||||
Instead of having to specify the value yourself, which could be an extensive array of information, you can use the "move" operation to move everything from one path to another.
|
|
||||||
|
|
||||||
## Apply the PATCH request header
|
## Apply the PATCH request header
|
||||||
|
|
||||||
With an operation, a path, and a change to make, a PATCH request is almost ready.
|
With an operation, a path, and a change to make, a PATCH request is almost ready.
|
||||||
|
|
||||||
To send the request as a PATCH, you must apply this special PATCH content type header: `Content-Type: application/json-patch+json`
|
To send the request as a PATCH, you must apply this special PATCH content type header: `Content-Type: application/json-patch+json`
|
||||||
|
|
||||||
## Send your PATCH request
|
## Send your PATCH request
|
||||||
|
|
||||||
Once you have specified the operation you want to apply, the path you want to change, the change you want to make, and you have applied the PATCH content type header, you can send your PATCH request.
|
Once you have specified the operation you want to apply, the path you want to change, the change you want to make, and you have applied the PATCH content type header, you can send your PATCH request.
|
||||||
|
|
||||||
When the request is successful, the API will return the updated resource.
|
When the request is successful, the API will return the updated resource.
|
||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
Now you can use PATCH requests partially update resources. For more information about PATCH requests, refer to this [documentation](https://datatracker.ietf.org/doc/html/rfc6902). For more information about the Identity Security Cloud PATCH endpoints and which paths can be changed for each one, refer to their API specifications.
|
Now you can use PATCH requests partially update resources. For more information about PATCH requests, refer to this [documentation](https://datatracker.ietf.org/doc/html/rfc6902). For more information about the Identity Security Cloud PATCH endpoints and which paths can be changed for each one, refer to their API specifications.
|
||||||
|
|
||||||
Use this guide to get started, and if you have questions, don't hesitate to reach out on the SailPoint Developer Community forum at https://developer.sailpoint.com/discuss!
|
Use this guide to get started, and if you have questions, don't hesitate to reach out on the SailPoint Developer Community forum at https://developer.sailpoint.com/discuss!
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ sidebar_label: Postman Collections
|
|||||||
sidebar_position: 7
|
sidebar_position: 7
|
||||||
sidebar_class_name: postmanCollections
|
sidebar_class_name: postmanCollections
|
||||||
keywords: ['postman']
|
keywords: ['postman']
|
||||||
description: Run ISC APIs in Postman.
|
description: Run ISC APIs in Postman.
|
||||||
tags: ['postman']
|
tags: ['postman']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
import GitHubPublicFileComponent from '@site/src/components/GitHubLink';
|
import GitHubPublicFileComponent from '@site/src/components/GitHubLink';
|
||||||
|
|
||||||
[Postman](https://www.postman.com/) is a platform you can use to design, build, test, and iterate your APIs. Postman users and teams can create public workspaces they can use to make it easy to access their API collections and environments and get started. SailPoint maintains a [public workspace for the Identity Security Cloud API collections](https://www.postman.com/sailpoint/workspace/identitynow). You can use this workspace to access all the ISC API collections and stay up to date.
|
[Postman](https://www.postman.com/) is a platform you can use to design, build, test, and iterate your APIs. Postman users and teams can create public workspaces they can use to make it easy to access their API collections and environments and get started. SailPoint maintains a [public workspace for the Identity Security Cloud API collections](https://www.postman.com/sailpoint/workspace/identitynow). You can use this workspace to access all the ISC API collections and stay up to date.
|
||||||
@@ -19,10 +18,8 @@ import GitHubPublicFileComponent from '@site/src/components/GitHubLink';
|
|||||||
|
|
||||||
Each ISC API version is broken out into a separate collection within the workspace. The following table lists the available ISC API collections. To import a collection into your workspace, select the 'Run in Postman' button for your desired version. Doing so forks the collection into your workspace.
|
Each ISC API version is broken out into a separate collection within the workspace. The following table lists the available ISC API collections. To import a collection into your workspace, select the 'Run in Postman' button for your desired version. Doing so forks the collection into your workspace.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| API | Postman Collection |
|
| API | Postman Collection |
|
||||||
|------|----------------------------|
|
| --- | --- |
|
||||||
| V3 API | [](https://god.gw.postman.com/run-collection/23226990-3721beea-5615-44b4-9459-e858a0ca7aed?action=collection%2Ffork&collection-url=entityId%3D23226990-3721beea-5615-44b4-9459-e858a0ca7aed%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
| V3 API | [](https://god.gw.postman.com/run-collection/23226990-3721beea-5615-44b4-9459-e858a0ca7aed?action=collection%2Ffork&collection-url=entityId%3D23226990-3721beea-5615-44b4-9459-e858a0ca7aed%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
||||||
| Beta API | [](https://god.gw.postman.com/run-collection/23226990-3b87172a-cd55-40a2-9ace-1560a1158a4e?action=collection%2Ffork&collection-url=entityId%3D23226990-3b87172a-cd55-40a2-9ace-1560a1158a4e%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
| Beta API | [](https://god.gw.postman.com/run-collection/23226990-3b87172a-cd55-40a2-9ace-1560a1158a4e?action=collection%2Ffork&collection-url=entityId%3D23226990-3b87172a-cd55-40a2-9ace-1560a1158a4e%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
||||||
| NERM API | [](https://god.gw.postman.com/run-collection/23226990-20d718e3-b9b3-43ad-850c-637b00864ae2?action=collection%2Ffork&collection-url=entityId%3D23226990-20d718e3-b9b3-43ad-850c-637b00864ae2%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
| NERM API | [](https://god.gw.postman.com/run-collection/23226990-20d718e3-b9b3-43ad-850c-637b00864ae2?action=collection%2Ffork&collection-url=entityId%3D23226990-20d718e3-b9b3-43ad-850c-637b00864ae2%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
||||||
@@ -41,12 +38,12 @@ SailPoint is often making improvements to the ISC API collections. To keep your
|
|||||||
The SailPoint workspace provides an environment, a set of variables you can use in your requests, that you can fork and pull changes from to stay up to date the same way you can with collections. To import the environment into your workspace, select 'Run in Postman'.
|
The SailPoint workspace provides an environment, a set of variables you can use in your requests, that you can fork and pull changes from to stay up to date the same way you can with collections. To import the environment into your workspace, select 'Run in Postman'.
|
||||||
|
|
||||||
| Environment | [](https://www.postman.com/sailpoint/workspace/identitynow/environment/23226990-ed571d4f-37a3-4a2c-9105-5d8d8cce1d20/fork) |
|
| Environment | [](https://www.postman.com/sailpoint/workspace/identitynow/environment/23226990-ed571d4f-37a3-4a2c-9105-5d8d8cce1d20/fork) |
|
||||||
|------|----------------------------|
|
| --- | --- |
|
||||||
|
|
||||||
To send API requests in Postman, you must authenticate to the APIs. To authenticate to the APIs, you must specify these variables in your Postman environment:
|
To send API requests in Postman, you must authenticate to the APIs. To authenticate to the APIs, you must specify these variables in your Postman environment:
|
||||||
|
|
||||||
| Environment Variable | Required | Description |
|
| Environment Variable | Required | Description |
|
||||||
| ----------- | ----------- | ----------- |
|
| --- | --- | --- |
|
||||||
| tenant | Yes | Your ISC tenant, typically your company's name |
|
| tenant | Yes | Your ISC tenant, typically your company's name |
|
||||||
| clientId | Yes | The client ID for the API client or personal access token |
|
| clientId | Yes | The client ID for the API client or personal access token |
|
||||||
| clientSecret | Yes | The client secret for the API client or personal access token |
|
| clientSecret | Yes | The client secret for the API client or personal access token |
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Rate Limiting
|
|||||||
sidebar_position: 6
|
sidebar_position: 6
|
||||||
sidebar_class_name: rateLimit
|
sidebar_class_name: rateLimit
|
||||||
keywords: ['rate limit']
|
keywords: ['rate limit']
|
||||||
description: ISC API rate limits.
|
description: ISC API rate limits.
|
||||||
tags: ['Rate Limit']
|
tags: ['Rate Limit']
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Standard Collection Parameters
|
|||||||
sidebar_position: 5
|
sidebar_position: 5
|
||||||
sidebar_class_name: standardCollectionParameters
|
sidebar_class_name: standardCollectionParameters
|
||||||
keywords: ['standard collection parameters']
|
keywords: ['standard collection parameters']
|
||||||
description: ISC API pagination, filtering, and sorting.
|
description: ISC API pagination, filtering, and sorting.
|
||||||
tags: ['Standard Collection Parameters']
|
tags: ['Standard Collection Parameters']
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -40,11 +40,11 @@ The `searchAfter` capability provides the ability to page on sorted field values
|
|||||||
|
|
||||||
**Required Properties for Paginating Search Results**
|
**Required Properties for Paginating Search Results**
|
||||||
|
|
||||||
|**Property**|Description|
|
| **Property** | Description |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|**query**|The Query JSON object. Refer to the following Query JSON Object table for details.|
|
| **query** | The Query JSON object. Refer to the following Query JSON Object table for details. |
|
||||||
|**sort**|The array list of the fields to sort by. This is required if you are using the `searchAfter` approach. You can use `-fieldName` for descending searches (optional).|
|
| **sort** | The array list of the fields to sort by. This is required if you are using the `searchAfter` approach. You can use `-fieldName` for descending searches (optional). |
|
||||||
|**searchAfter**|You can use this instead of offset to get past the 10,000 paging result record limit, passing the last value(s) of your sort fields from the previous result set into the next result set until you get the total number of results or the end of results (optional).|
|
| **searchAfter** | You can use this instead of offset to get past the 10,000 paging result record limit, passing the last value(s) of your sort fields from the previous result set into the next result set until you get the total number of results or the end of results (optional). |
|
||||||
|
|
||||||
### Example of Paginating Search Results
|
### Example of Paginating Search Results
|
||||||
|
|
||||||
@@ -54,15 +54,11 @@ Here is an example of a search API call with `searchAfter` paging. The first que
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"indices": [
|
"indices": ["identities"],
|
||||||
"identities"
|
"query": {
|
||||||
],
|
"query": "*"
|
||||||
"query": {
|
},
|
||||||
"query": "*"
|
"sort": ["id"]
|
||||||
},
|
|
||||||
"sort": [
|
|
||||||
"id"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -72,16 +68,12 @@ This query will return 100 records. To get the next 100 records, find the last r
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"indices": [
|
"indices": ["identities"],
|
||||||
"identities"
|
"query": {
|
||||||
],
|
"query": "*"
|
||||||
"query": {
|
},
|
||||||
"query": "*"
|
"sort": ["id"],
|
||||||
},
|
"searchAfter": ["2c9180835d38ca0c015d606b50851b1e"]
|
||||||
"sort": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"searchAfter": ["2c9180835d38ca0c015d606b50851b1e"]
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Connectivity
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: connectivity
|
sidebar_class_name: connectivity
|
||||||
keywords: ['connectivity']
|
keywords: ['connectivity']
|
||||||
description: Build and expand ISC connectivity.
|
description: Build and expand ISC connectivity.
|
||||||
slug: /connectivity
|
slug: /connectivity
|
||||||
tags: ['connectivity']
|
tags: ['connectivity']
|
||||||
---
|
---
|
||||||
@@ -24,6 +24,6 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
|
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
To learn more about ISC connectivity and discuss it with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
To learn more about ISC connectivity and discuss it with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
||||||
|
|||||||
@@ -37,4 +37,3 @@ Below is a list of commands and their usages:
|
|||||||
- Delete a connector: `sail conn delete -c [connectorID | connectorAlias]`
|
- Delete a connector: `sail conn delete -c [connectorID | connectorAlias]`
|
||||||
- **Linking**
|
- **Linking**
|
||||||
- Link a customizer to your source instance: `sail conn customizers link -i [sourceInstanceID] -c [customizerID]`
|
- Link a customizer to your source instance: `sail conn customizers link -i [sourceInstanceID] -c [customizerID]`
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ slug: /connectivity/saas-connectivity/commands/account-enable
|
|||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :-------------- | :---------------------: |
|
| :-------------- | :--------------------: |
|
||||||
| Input - Enable | StdAccountEnableInput |
|
| Input - Enable | StdAccountEnableInput |
|
||||||
| Output - Enable | StdAccountEnableOutput |
|
| Output - Enable | StdAccountEnableOutput |
|
||||||
|
|
||||||
### Example StdAccountEnableInput
|
### Example StdAccountEnableInput
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ ISC will throw a connection timeout error if your connector doesn't respond with
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
ISC supports [delta aggregation](#delta-aggregation-state). If your source has a large number of accounts that will be syncronized with ISC, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
|
ISC supports [delta aggregation](#delta-aggregation-state). If your source has a large number of accounts that will be syncronized with ISC, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ The result of the account list command is not an array of objects but several in
|
|||||||
|
|
||||||
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
|
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
|
||||||
|
|
||||||
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: ```"supportsStatefulCommands": true,``` and in the sourceConfig section, a checkbox needs to be added to enable state with the key ```spConnEnableStatefulCommands```:
|
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: `"supportsStatefulCommands": true,` and in the sourceConfig section, a checkbox needs to be added to enable state with the key `spConnEnableStatefulCommands`:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
"supportsStatefulCommands": true,
|
"supportsStatefulCommands": true,
|
||||||
@@ -193,7 +193,7 @@ If your source can keep track of changes to the data in some way, then delta agg
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. In the ```stdAccountList``` command, when you are done sending accounts, you need to also send the state to ISC so it knows where to start the next time it sends a list request:
|
2. In the `stdAccountList` command, when you are done sending accounts, you need to also send the state to ISC so it knows where to start the next time it sends a list request:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const state = {"data": Date.now().toString()}
|
const state = {"data": Date.now().toString()}
|
||||||
@@ -205,11 +205,11 @@ In the above example, I am capturing the date, but you can use any value you wan
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
The state that you send using the ```saveState``` command MUST be a json object, and it is recommend to only save strings to ensure proper serialization/deserialization of the data. You cannot send a simple string or number or it will not properly save the state.
|
The state that you send using the `saveState` command MUST be a json object, and it is recommend to only save strings to ensure proper serialization/deserialization of the data. You cannot send a simple string or number or it will not properly save the state.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
3. In the ```stdAccountList``` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
|
3. In the `stdAccountList` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdAccountList(async (context: Context, input: StdAccountListInput, res: Response<StdAccountListOutput>) => {
|
.stdAccountList(async (context: Context, input: StdAccountListInput, res: Response<StdAccountListOutput>) => {
|
||||||
@@ -231,4 +231,4 @@ The state that you send using the ```saveState``` command MUST be a json object,
|
|||||||
}
|
}
|
||||||
res.saveState(state)
|
res.saveState(state)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -105,4 +105,4 @@ Note: Testing the account update command for removing entitlements using this me
|
|||||||
|
|
||||||
## Handling an account that is not found
|
## Handling an account that is not found
|
||||||
|
|
||||||
If an account can't be found in the source system, ISC can recreate the account by using the ```ConnectorErrorType.NotFound``` error type. For details and implementation, refer to [Error Handling](../in-depth/error-handling.md#not-found-error-type).
|
If an account can't be found in the source system, ISC can recreate the account by using the `ConnectorErrorType.NotFound` error type. For details and implementation, refer to [Error Handling](../in-depth/error-handling.md#not-found-error-type).
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ slug: /connectivity/saas-connectivity/commands/change-password
|
|||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :--------------------: |
|
| :----------- | :---------------------: |
|
||||||
| Input | StdChangePasswordInput |
|
| Input | StdChangePasswordInput |
|
||||||
| Output | StdChangePasswordOutput |
|
| Output | StdChangePasswordOutput |
|
||||||
|
|
||||||
@@ -29,12 +29,13 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
### Example StdChangePasswordOutput
|
### Example StdChangePasswordOutput
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
The change password command is triggered in ISC when a user changes their password through ISC. When this occurs, if your source has change password enabled, then you can change the user password on the source system through ISC.
|
The change password command is triggered in ISC when a user changes their password through ISC. When this occurs, if your source has change password enabled, then you can change the user password on the source system through ISC.
|
||||||
|
|
||||||
## The Provisioning Plan
|
## The Provisioning Plan
|
||||||
|
|
||||||
@@ -48,4 +49,4 @@ The change password command sends the password change event to your connector wh
|
|||||||
|
|
||||||
## Testing in Identity Security Cloud
|
## Testing in Identity Security Cloud
|
||||||
|
|
||||||
In order to test in Identity Security Cloud, the source application must be configured so that it is able to accept password change requests through the Password Manager. Once this setup is complete, you can log in as a user whose identity exists in the configured application and change their password in the Password Manager.
|
In order to test in Identity Security Cloud, the source application must be configured so that it is able to accept password change requests through the Password Manager. Once this setup is complete, you can log in as a user whose identity exists in the configured application and change their password in the Password Manager.
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ private buildStandardObject(): StdEntitlementReadOutput | StdEntitlementListOutp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
ISC will throw a connection timeout error if your connector doesn't respond within 3 minutes, and there are memory limitations involved with aggregating data. To prevent large memory utilization or timeout errors, you should set up your connectors to send data to ISC as it's retrieved from your source system. For more details and an example, refer to [Connector Timeouts](../in-depth/connector-timeouts.md).
|
ISC will throw a connection timeout error if your connector doesn't respond within 3 minutes, and there are memory limitations involved with aggregating data. To prevent large memory utilization or timeout errors, you should set up your connectors to send data to ISC as it's retrieved from your source system. For more details and an example, refer to [Connector Timeouts](../in-depth/connector-timeouts.md).
|
||||||
@@ -112,7 +113,7 @@ ISC will throw a connection timeout error if your connector doesn't respond with
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
ISC supports [delta aggregation](#delta-aggregation-state). If your source has a large number of entitlements that will be syncronized with ISC, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
|
ISC supports [delta aggregation](#delta-aggregation-state). If your source has a large number of entitlements that will be syncronized with ISC, then it is highly recommended to utilize [delta aggregation](#delta-aggregation-state) for the source.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ ISC supports [delta aggregation](#delta-aggregation-state). If your source has a
|
|||||||
|
|
||||||
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
|
If your source can keep track of changes to the data in some way, then delta aggregation can be performed on a source. In order to implement, there are a few things that need to be configured
|
||||||
|
|
||||||
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: ```"supportsStatefulCommands": true,``` and in the sourceConfig section, a checkbox needs to be added to enable state with the key ```spConnEnableStatefulCommands```:
|
1. In your connector-spec.json file, the feature needs to be enabled by adding the following key: `"supportsStatefulCommands": true,` and in the sourceConfig section, a checkbox needs to be added to enable state with the key `spConnEnableStatefulCommands`:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
"supportsStatefulCommands": true,
|
"supportsStatefulCommands": true,
|
||||||
@@ -133,7 +134,7 @@ If your source can keep track of changes to the data in some way, then delta agg
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
2. In the ```stdEntitlementList``` command, when you are done sending entitlments, you need to also send the state to ISC so it knows where to start the next time it sends a list request:
|
2. In the `stdEntitlementList` command, when you are done sending entitlments, you need to also send the state to ISC so it knows where to start the next time it sends a list request:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const state = {"data": Date.now().toString()}
|
const state = {"data": Date.now().toString()}
|
||||||
@@ -145,11 +146,11 @@ In the above example, I am capturing the date, but you can use any value you wan
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
The state that you send using the ```saveState``` command MUST be a json object, and it is recommend to only save strings to ensure proper serialization/deserialization of the data. You cannot send a simple string or number or it will not properly save the state.
|
The state that you send using the `saveState` command MUST be a json object, and it is recommend to only save strings to ensure proper serialization/deserialization of the data. You cannot send a simple string or number or it will not properly save the state.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
3. In the ```stdEntitlementList``` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
|
3. In the `stdEntitlementList` command, you need to properly handle the state object. Something like below checks the stateful boolean as well as the state object and fetches accounts accordingly:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdEntitlementList(async (context: Context, input: StdEntitlementListInput, res: Response<StdEntitlementListOutput>) => {
|
.stdEntitlementList(async (context: Context, input: StdEntitlementListInput, res: Response<StdEntitlementListOutput>) => {
|
||||||
@@ -171,4 +172,4 @@ The state that you send using the ```saveState``` command MUST be a json object,
|
|||||||
}
|
}
|
||||||
res.saveState(state)
|
res.saveState(state)
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ title: Source Data Discover
|
|||||||
pagination_label: Source Data Discover
|
pagination_label: Source Data Discover
|
||||||
sidebar_label: Source Data Discover
|
sidebar_label: Source Data Discover
|
||||||
keywords: ['connectivity', 'connectors', 'Source Data Discover']
|
keywords: ['connectivity', 'connectors', 'Source Data Discover']
|
||||||
description: Discover potential source data types.
|
description: Discover potential source data types.
|
||||||
slug: /connectivity/saas-connectivity/commands/source-data-discover
|
slug: /connectivity/saas-connectivity/commands/source-data-discover
|
||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :-------------------------: |
|
| :----------- | :-------------------------: |
|
||||||
| Input | StdSourceDataDiscoverInput |
|
| Input | StdSourceDataDiscoverInput |
|
||||||
| Output | StdSourceDataDiscoverOutput |
|
| Output | StdSourceDataDiscoverOutput |
|
||||||
@@ -29,26 +29,26 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
subLabel: 'Airtable Base Id'
|
subLabel: 'Airtable Base Id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
subLabel: 'Airtable Source Table Name'
|
subLabel: 'Airtable Source Table Name',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Use the source data discover command to identify the types of data your source can return. Different sources can send different types of data to Identity Security Cloud. For example, one source may be able to send a list of the different languages it supports, while another may be able to send values describing source details normally sent through accounts and entitlements. You can use the source data discover command to discover these possibilities.
|
Use the source data discover command to identify the types of data your source can return. Different sources can send different types of data to Identity Security Cloud. For example, one source may be able to send a list of the different languages it supports, while another may be able to send values describing source details normally sent through accounts and entitlements. You can use the source data discover command to discover these possibilities.
|
||||||
|
|
||||||
One typical use for the source data discover command is found in Identity Security Cloud customer forms for dropdown menus: they use the command to identify the additional source types their sources can provide to Identity Security Cloud and use that information to populate the dropdown menus.
|
One typical use for the source data discover command is found in Identity Security Cloud customer forms for dropdown menus: they use the command to identify the additional source types their sources can provide to Identity Security Cloud and use that information to populate the dropdown menus.
|
||||||
|
|
||||||
This is a simple example of the source data discover command. It has been implemented to list two types of queries that the Airtable source can supply.
|
This is a simple example of the source data discover command. It has been implemented to list two types of queries that the Airtable source can supply.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdSourceDataDiscover(async (context: Context, input: StdSourceDataDiscoverInput, res: Response<StdSourceDataDiscoverOutput>) => {
|
.stdSourceDataDiscover(async (context: Context, input: StdSourceDataDiscoverInput, res: Response<StdSourceDataDiscoverOutput>) => {
|
||||||
@@ -103,4 +103,4 @@ Now, if the source system sends a command like the following, they will only get
|
|||||||
"query": "name"
|
"query": "name"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ title: Source Data Read
|
|||||||
pagination_label: Source Data Read
|
pagination_label: Source Data Read
|
||||||
sidebar_label: Source Data Read
|
sidebar_label: Source Data Read
|
||||||
keywords: ['connectivity', 'connectors', 'Source Data Read']
|
keywords: ['connectivity', 'connectors', 'Source Data Read']
|
||||||
description: Read source data.
|
description: Read source data.
|
||||||
slug: /connectivity/saas-connectivity/commands/source-data-read
|
slug: /connectivity/saas-connectivity/commands/source-data-read
|
||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :-------------------------: |
|
| :----------- | :---------------------: |
|
||||||
| Input | StdSourceDataReadInput |
|
| Input | StdSourceDataReadInput |
|
||||||
| Output | StdSourceDataReadOutput |
|
| Output | StdSourceDataReadOutput |
|
||||||
|
|
||||||
@@ -30,24 +30,24 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
subLabel: 'Airtable Base Id'
|
subLabel: 'Airtable Base Id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
subLabel: 'Airtable Source Table Name'
|
subLabel: 'Airtable Source Table Name',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
Use the source data read command to query a source in Identity Security Cloud and return a set of data. This data is typically used to populate a dropdown menu for selection purposes. This functionality is typically useful for Identity Security Cloud forms, but it can be used for any type of implementation that requires you to get other information from a source, information that is not normally retrieved from identites or entitlements.
|
Use the source data read command to query a source in Identity Security Cloud and return a set of data. This data is typically used to populate a dropdown menu for selection purposes. This functionality is typically useful for Identity Security Cloud forms, but it can be used for any type of implementation that requires you to get other information from a source, information that is not normally retrieved from identites or entitlements.
|
||||||
|
|
||||||
This is a simple example of the source data read command. It is implemented to retrieve the base ID name. The `sourceDataKey` is required, the ```source data read``` command should return it.
|
This is a simple example of the source data read command. It is implemented to retrieve the base ID name. The `sourceDataKey` is required, the `source data read` command should return it.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdSourceDataRead(async (context: Context, input: StdSourceDataReadInput, res: Response<StdSourceDataReadOutput>) => {
|
.stdSourceDataRead(async (context: Context, input: StdSourceDataReadInput, res: Response<StdSourceDataReadOutput>) => {
|
||||||
@@ -63,7 +63,7 @@ This is a simple example of the source data read command. It is implemented to r
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
You can optionally use `input.queryInput.query` to make the list searchable. One way you could do this is to import a tool like [alasql](https://github.com/AlaSQL/alasql) and allow the user to implement a search on the dataset. This example from Airtable shows how you could use the source data read command to get accounts and allow a search to be performed with the Airtable API:
|
You can optionally use `input.queryInput.query` to make the list searchable. One way you could do this is to import a tool like [alasql](https://github.com/AlaSQL/alasql) and allow the user to implement a search on the dataset. This example from Airtable shows how you could use the source data read command to get accounts and allow a search to be performed with the Airtable API:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdSourceDataRead(async (context: Context, input: StdSourceDataReadInput, res: Response<StdSourceDataReadOutput>) => {
|
.stdSourceDataRead(async (context: Context, input: StdSourceDataReadInput, res: Response<StdSourceDataReadOutput>) => {
|
||||||
@@ -113,4 +113,4 @@ Now, if the source system sends a command like the following, the system will on
|
|||||||
"query": "Adam"
|
"query": "Adam"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ The connector config object holds all the config values that are set in the SaaS
|
|||||||
The config object is fetched during initialization of the connector
|
The config object is fetched during initialization of the connector
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
const config: Config = await readConfig()
|
const config: Config = await readConfig();
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example Config Object
|
### Example Config Object
|
||||||
@@ -27,36 +27,36 @@ Below is an example object model that can be used to type your config. Any value
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
export interface Config {
|
export interface Config {
|
||||||
beforeProvisioningRule: any
|
beforeProvisioningRule: any;
|
||||||
cloudCacheUpdate: number
|
cloudCacheUpdate: number;
|
||||||
cloudDisplayName: string
|
cloudDisplayName: string;
|
||||||
cloudExternalId: string
|
cloudExternalId: string;
|
||||||
connectionType: string
|
connectionType: string;
|
||||||
connectorName: string
|
connectorName: string;
|
||||||
deleteThresholdPercentage: number
|
deleteThresholdPercentage: number;
|
||||||
deltaAggregation: DeltaAggregation
|
deltaAggregation: DeltaAggregation;
|
||||||
deltaAggregationEnabled: boolean
|
deltaAggregationEnabled: boolean;
|
||||||
formPath: any
|
formPath: any;
|
||||||
hasFullAggregationCompleted: boolean
|
hasFullAggregationCompleted: boolean;
|
||||||
healthCheckTimeout: number
|
healthCheckTimeout: number;
|
||||||
healthy: boolean
|
healthy: boolean;
|
||||||
idnProxyType: string
|
idnProxyType: string;
|
||||||
managementWorkgroup: any
|
managementWorkgroup: any;
|
||||||
managerCorrelationFilter: any
|
managerCorrelationFilter: any;
|
||||||
since: string
|
since: string;
|
||||||
"slpt-source-diagnostics": string
|
'slpt-source-diagnostics': string;
|
||||||
sourceConnected: boolean
|
sourceConnected: boolean;
|
||||||
sourceDescription: string
|
sourceDescription: string;
|
||||||
spConnEnableStatefulCommands: boolean
|
spConnEnableStatefulCommands: boolean;
|
||||||
spConnectorInstanceId: string
|
spConnectorInstanceId: string;
|
||||||
spConnectorSpecId: string
|
spConnectorSpecId: string;
|
||||||
status: string
|
status: string;
|
||||||
supportsDeltaAgg: boolean
|
supportsDeltaAgg: boolean;
|
||||||
templateApplication: string
|
templateApplication: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DeltaAggregation {
|
export interface DeltaAggregation {
|
||||||
"std:account:list": any
|
'std:account:list': any;
|
||||||
"std:entitlement:list": any
|
'std:entitlement:list': any;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ title: Account Create
|
|||||||
pagination_label: Account Create
|
pagination_label: Account Create
|
||||||
sidebar_label: Account Create
|
sidebar_label: Account Create
|
||||||
keywords: ['connectivity', 'connectors', 'Account Create']
|
keywords: ['connectivity', 'connectors', 'Account Create']
|
||||||
description: Intercept the account create command.
|
description: Intercept the account create command.
|
||||||
slug: /connectivity/saas-connectivity/customizers/commands/account-create
|
slug: /connectivity/saas-connectivity/customizers/commands/account-create
|
||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-create](../../commands/account-create) command.
|
Use these commands to intercept the [account-create](../../commands/account-create) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :--------------------: |
|
| :----------- | :--------------------: |
|
||||||
| Input | StdAccountCreateInput |
|
| Input | StdAccountCreateInput |
|
||||||
@@ -60,11 +59,12 @@ Use these commands to intercept the [account-create](../../commands/account-crea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-create command
|
### Before account-create command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountCreate(async (context: Context, input: StdAccountCreateInput) => {
|
.beforeStdAccountCreate(async (context: Context, input: StdAccountCreateInput) => {
|
||||||
@@ -72,11 +72,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-create command
|
### After account-create command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountCreate(async (context: Context, output: StdAccountCreateOutput) => {
|
.afterStdAccountCreate(async (context: Context, output: StdAccountCreateOutput) => {
|
||||||
@@ -84,4 +85,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ title: Account Delete
|
|||||||
pagination_label: Account Delete
|
pagination_label: Account Delete
|
||||||
sidebar_label: Account Delete
|
sidebar_label: Account Delete
|
||||||
keywords: ['connectivity', 'connectors', 'Account Delete']
|
keywords: ['connectivity', 'connectors', 'Account Delete']
|
||||||
description: Intercept the account delete command.
|
description: Intercept the account delete command.
|
||||||
slug: /connectivity/saas-connectivity/customizers/commands/account-delete
|
slug: /connectivity/saas-connectivity/customizers/commands/account-delete
|
||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
@@ -37,11 +37,12 @@ Use these commands to intercept the [account-delete](../../commands/account-dele
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-delete command
|
### Before account-delete command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountDelete(async (context: Context, input: StdAccountDeleteInput) => {
|
.beforeStdAccountDelete(async (context: Context, input: StdAccountDeleteInput) => {
|
||||||
@@ -49,11 +50,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-delete command
|
### After account-delete command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountDelete(async (context: Context, output: StdAccountDeleteOutput) => {
|
.afterStdAccountDelete(async (context: Context, output: StdAccountDeleteOutput) => {
|
||||||
@@ -61,4 +63,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ title: Account Disable
|
|||||||
pagination_label: Account Disable
|
pagination_label: Account Disable
|
||||||
sidebar_label: Account Disable
|
sidebar_label: Account Disable
|
||||||
keywords: ['connectivity', 'connectors', 'Account Disable']
|
keywords: ['connectivity', 'connectors', 'Account Disable']
|
||||||
description: Intercept the account disable command.
|
description: Intercept the account disable command.
|
||||||
slug: /connectivity/saas-connectivity/customizers/commands/account-disable
|
slug: /connectivity/saas-connectivity/customizers/commands/account-disable
|
||||||
tags: ['Connectivity', 'Connector Command']
|
tags: ['Connectivity', 'Connector Command']
|
||||||
---
|
---
|
||||||
@@ -13,11 +13,10 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-disable](../../commands/account-disable) command.
|
Use these commands to intercept the [account-disable](../../commands/account-disable) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :---------------------: |
|
||||||
| :-------------- | :---------------------: |
|
| Input | StdAccountDisableInput |
|
||||||
| Input | StdAccountDisableInput |
|
| Output | StdAccountDisableOutput |
|
||||||
| Output | StdAccountDisableOutput |
|
|
||||||
|
|
||||||
### Example StdAccountDisableInput
|
### Example StdAccountDisableInput
|
||||||
|
|
||||||
@@ -53,11 +52,12 @@ Use these commands to intercept the [account-disable](../../commands/account-dis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-disable command
|
### Before account-disable command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountDisable(async (context: Context, input: StdAccountDisableInput) => {
|
.beforeStdAccountDisable(async (context: Context, input: StdAccountDisableInput) => {
|
||||||
@@ -65,11 +65,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-disable command
|
### After account-disable command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountDisable(async (context: Context, output: StdAccountDisableOutput) => {
|
.afterStdAccountDisable(async (context: Context, output: StdAccountDisableOutput) => {
|
||||||
@@ -77,4 +78,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,11 +13,10 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-enable](../../commands/account-enable) command.
|
Use these commands to intercept the [account-enable](../../commands/account-enable) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :--------------------: |
|
||||||
| :-------------- | :---------------------: |
|
| Input | StdAccountEnableInput |
|
||||||
| Input | StdAccountEnableInput |
|
| Output | StdAccountEnableOutput |
|
||||||
| Output | StdAccountEnableOutput |
|
|
||||||
|
|
||||||
### Example StdAccountEnableInput
|
### Example StdAccountEnableInput
|
||||||
|
|
||||||
@@ -53,11 +52,12 @@ Use these commands to intercept the [account-enable](../../commands/account-enab
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-enable command
|
### Before account-enable command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountEnable(async (context: Context, input: StdAccountEnableInput) => {
|
.beforeStdAccountEnable(async (context: Context, input: StdAccountEnableInput) => {
|
||||||
@@ -65,11 +65,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-enable command
|
### After account-enable command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountEnable(async (context: Context, output: StdAccountEnableOutput) => {
|
.afterStdAccountEnable(async (context: Context, output: StdAccountEnableOutput) => {
|
||||||
@@ -77,4 +78,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-list](../../commands/account-list) command.
|
Use these commands to intercept the [account-list](../../commands/account-list) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :-----------------: |
|
||||||
| :----------- | :------------------: |
|
| Input | StdAccountListInput |
|
||||||
| Input | StdAccountListInput |
|
|
||||||
|
|
||||||
### Example StdAccountListInput
|
### Example StdAccountListInput
|
||||||
|
|
||||||
@@ -24,11 +23,12 @@ Use these commands to intercept the [account-list](../../commands/account-list)
|
|||||||
"state": {"date": "1686341338871"},
|
"state": {"date": "1686341338871"},
|
||||||
"stateful": true
|
"stateful": true
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-list command
|
### Before account-list command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountList(async (context: Context, input: StdAccountListInput) => {
|
.beforeStdAccountList(async (context: Context, input: StdAccountListInput) => {
|
||||||
@@ -36,8 +36,9 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-list command
|
### After account-list command
|
||||||
|
|
||||||
After account-list is not available for customization at this time. If you need to modify the values of the response, it is recommended that you use [Transforms](https://developer.sailpoint.com/docs/extensibility/transforms/).
|
After account-list is not available for customization at this time. If you need to modify the values of the response, it is recommended that you use [Transforms](https://developer.sailpoint.com/docs/extensibility/transforms/).
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-read](../../commands/account-read) command.
|
Use these commands to intercept the [account-read](../../commands/account-read) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :------------------: |
|
| :----------- | :------------------: |
|
||||||
| Input | StdAccountReadInput |
|
| Input | StdAccountReadInput |
|
||||||
@@ -53,12 +52,12 @@ Use these commands to intercept the [account-read](../../commands/account-read)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## Implementation
|
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
### Before account-read command
|
### Before account-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountRead(async (context: Context, input: StdAccountReadInput) => {
|
.beforeStdAccountRead(async (context: Context, input: StdAccountReadInput) => {
|
||||||
@@ -66,11 +65,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-read command
|
### After account-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountRead(async (context: Context, output: StdAccountReadOutput) => {
|
.afterStdAccountRead(async (context: Context, output: StdAccountReadOutput) => {
|
||||||
@@ -78,4 +78,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-unlock](../../commands/account-unlock) command.
|
Use these commands to intercept the [account-unlock](../../commands/account-unlock) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :--------------------: |
|
| :----------- | :--------------------: |
|
||||||
| Input | StdAccountUnlockInput |
|
| Input | StdAccountUnlockInput |
|
||||||
@@ -53,11 +52,12 @@ Use these commands to intercept the [account-unlock](../../commands/account-unlo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before account-unlock command
|
### Before account-unlock command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountUnlock(async (context: Context, input: StdAccountUnlockInput) => {
|
.beforeStdAccountUnlock(async (context: Context, input: StdAccountUnlockInput) => {
|
||||||
@@ -65,11 +65,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-unlock command
|
### After account-unlock command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountUnlock(async (context: Context, output: StdAccountUnlockOutput) => {
|
.afterStdAccountUnlock(async (context: Context, output: StdAccountUnlockOutput) => {
|
||||||
@@ -77,4 +78,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [account-update](../../commands/account-update) command.
|
Use these commands to intercept the [account-update](../../commands/account-update) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :--------------------: |
|
| :----------- | :--------------------: |
|
||||||
| Input | StdAccountUpdateInput |
|
| Input | StdAccountUpdateInput |
|
||||||
@@ -62,12 +61,12 @@ Use these commands to intercept the [account-update](../../commands/account-upda
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
## Implementation
|
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
### Before account-update command
|
### Before account-update command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdAccountUpdate(async (context: Context, input: StdAccountUpdateInput) => {
|
.beforeStdAccountUpdate(async (context: Context, input: StdAccountUpdateInput) => {
|
||||||
@@ -75,11 +74,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After account-update command
|
### After account-update command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdAccountUpdate(async (context: Context, output: StdAccountUpdateOutput) => {
|
.afterStdAccountUpdate(async (context: Context, output: StdAccountUpdateOutput) => {
|
||||||
@@ -87,4 +87,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [change-password](../../commands/change-password) command.
|
Use these commands to intercept the [change-password](../../commands/change-password) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :---------------------: |
|
||||||
| :----------- | :--------------------: |
|
|
||||||
| Input | StdChangePasswordInput |
|
| Input | StdChangePasswordInput |
|
||||||
| Output | StdChangePasswordOutput |
|
| Output | StdChangePasswordOutput |
|
||||||
|
|
||||||
@@ -34,14 +33,15 @@ Use these commands to intercept the [change-password](../../commands/change-pass
|
|||||||
### Example StdChangePasswordOutput
|
### Example StdChangePasswordOutput
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
```
|
```
|
||||||
## Implementation
|
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
### Before change-password command
|
### Before change-password command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdChangePassword(async (context: Context, input: StdChangePasswordInput) => {
|
.beforeStdChangePassword(async (context: Context, input: StdChangePasswordInput) => {
|
||||||
@@ -49,11 +49,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After change-password command
|
### After change-password command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdChangePassword(async (context: Context, output: StdChangePasswordOutput) => {
|
.afterStdChangePassword(async (context: Context, output: StdChangePasswordOutput) => {
|
||||||
@@ -61,4 +62,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [entitlement-list](../../commands/entitlement-list) command.
|
Use these commands to intercept the [entitlement-list](../../commands/entitlement-list) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :---------------------: |
|
||||||
| :----------- | :----------------------: |
|
| Input | StdEntitlementListInput |
|
||||||
| Input | StdEntitlementListInput |
|
|
||||||
|
|
||||||
### Example StdEntitlementListInput
|
### Example StdEntitlementListInput
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ Use these commands to intercept the [entitlement-list](../../commands/entitlemen
|
|||||||
|
|
||||||
### Before entitlement-list command
|
### Before entitlement-list command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdEntitlementList(async (context: Context, input: StdEntitlementListInput) => {
|
.beforeStdEntitlementList(async (context: Context, input: StdEntitlementListInput) => {
|
||||||
@@ -38,8 +37,9 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After entitlement-list command
|
### After entitlement-list command
|
||||||
|
|
||||||
After entitlement-list is not available for customization at this time. If you need to modify the values of the response, it is recommended that you use [Transforms](https://developer.sailpoint.com/docs/extensibility/transforms/).
|
After entitlement-list is not available for customization at this time. If you need to modify the values of the response, it is recommended that you use [Transforms](https://developer.sailpoint.com/docs/extensibility/transforms/).
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [entitlement-read](../../commands/entitlement-read) command.
|
Use these commands to intercept the [entitlement-read](../../commands/entitlement-read) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :----------------------: |
|
| :----------- | :----------------------: |
|
||||||
| Input | StdEntitlementReadInput |
|
| Input | StdEntitlementReadInput |
|
||||||
@@ -50,11 +49,12 @@ Use these commands to intercept the [entitlement-read](../../commands/entitlemen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before entitlement-read command
|
### Before entitlement-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdEntitlementRead(async (context: Context, input: StdEntitlementReadInput) => {
|
.beforeStdEntitlementRead(async (context: Context, input: StdEntitlementReadInput) => {
|
||||||
@@ -62,11 +62,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After entitlement-read command
|
### After entitlement-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdEntitlementRead(async (context: Context, output: StdEntitlementReadOutput) => {
|
.afterStdEntitlementRead(async (context: Context, output: StdEntitlementReadOutput) => {
|
||||||
@@ -74,4 +75,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [source-data-discover](../../commands/source-data-discover) command.
|
Use these commands to intercept the [source-data-discover](../../commands/source-data-discover) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
|
||||||
| :----------- | :-------------------------: |
|
| :----------- | :-------------------------: |
|
||||||
| Input | StdSourceDataDiscoverInput |
|
| Input | StdSourceDataDiscoverInput |
|
||||||
| Output | StdSourceDataDiscoverOutput |
|
| Output | StdSourceDataDiscoverOutput |
|
||||||
@@ -34,23 +33,24 @@ Use these commands to intercept the [source-data-discover](../../commands/source
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
subLabel: 'Airtable Base Id'
|
subLabel: 'Airtable Base Id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
subLabel: 'Airtable Source Table Name'
|
subLabel: 'Airtable Source Table Name',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before source-data-discover command
|
### Before source-data-discover command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdSourceDataDiscover(async (context: Context, input: StdSourceDataDiscoverInput) => {
|
.beforeStdSourceDataDiscover(async (context: Context, input: StdSourceDataDiscoverInput) => {
|
||||||
@@ -58,11 +58,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After source-data-discover command
|
### After source-data-discover command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdSourceDataDiscover(async (context: Context, output: StdSourceDataDiscoverOutput) => {
|
.afterStdSourceDataDiscover(async (context: Context, output: StdSourceDataDiscoverOutput) => {
|
||||||
@@ -70,4 +71,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,9 +13,8 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [source-data-read](../../commands/source-data-read) command.
|
Use these commands to intercept the [source-data-read](../../commands/source-data-read) command.
|
||||||
|
|
||||||
|
| Input/Output | Data Type |
|
||||||
| Input/Output | Data Type |
|
| :----------- | :---------------------: |
|
||||||
| :----------- | :-------------------------: |
|
|
||||||
| Input | StdSourceDataReadInput |
|
| Input | StdSourceDataReadInput |
|
||||||
| Output | StdSourceDataReadOutput |
|
| Output | StdSourceDataReadOutput |
|
||||||
|
|
||||||
@@ -35,23 +34,24 @@ Use these commands to intercept the [source-data-read](../../commands/source-dat
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
key: 'id',
|
key: 'id',
|
||||||
label: 'Id',
|
label: 'Id',
|
||||||
subLabel: 'Airtable Base Id'
|
subLabel: 'Airtable Base Id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'name',
|
key: 'name',
|
||||||
label: 'Name',
|
label: 'Name',
|
||||||
subLabel: 'Airtable Source Table Name'
|
subLabel: 'Airtable Source Table Name',
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before source-data-read command
|
### Before source-data-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdSourceDataRead(async (context: Context, input: StdSourceDataReadInput) => {
|
.beforeStdSourceDataRead(async (context: Context, input: StdSourceDataReadInput) => {
|
||||||
@@ -59,11 +59,12 @@ Use this logic to implement the command:
|
|||||||
return input
|
return input
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
The `input` object can be mutated and returned, but the same data type must still be returned.
|
The `input` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|
||||||
### After source-data-read command
|
### After source-data-read command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdSourceDataRead(async (context: Context, output: StdSourceDataReadOutput) => {
|
.afterStdSourceDataRead(async (context: Context, output: StdSourceDataReadOutput) => {
|
||||||
@@ -71,4 +72,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The `output` object can be mutated and returned, but the same data type must still be returned.
|
|
||||||
|
The `output` object can be mutated and returned, but the same data type must still be returned.
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ tags: ['Connectivity', 'Connector Command']
|
|||||||
|
|
||||||
Use these commands to intercept the [Test-Connection](../../commands/test-connection) command.
|
Use these commands to intercept the [Test-Connection](../../commands/test-connection) command.
|
||||||
|
|
||||||
|
|
||||||
| Input/Output | Data Type |
|
| Input/Output | Data Type |
|
||||||
| :----------- | :---------------------: |
|
| :----------- | :---------------------: |
|
||||||
| Input | undefined |
|
| Input | undefined |
|
||||||
@@ -25,22 +24,24 @@ Use these commands to intercept the [Test-Connection](../../commands/test-connec
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Implementation
|
## Implementation
|
||||||
|
|
||||||
### Before test-connection command
|
### Before test-connection command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.beforeStdTestConnection(async (context: Context, input: undefined) => {
|
.beforeStdTestConnection(async (context: Context, input: undefined) => {
|
||||||
logger.info('Running before test connection')
|
logger.info('Running before test connection')
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
There is no input, so you cannot mutate any data. However, you can make web request calls or perform any type of logging or logic before calling the connector.
|
There is no input, so you cannot mutate any data. However, you can make web request calls or perform any type of logging or logic before calling the connector.
|
||||||
|
|
||||||
### After test-connection command
|
### After test-connection command
|
||||||
|
|
||||||
Use this logic to implement the command:
|
Use this logic to implement the command:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.afterStdTestConnection(async (context: Context, output: StdTestConnectionOutput) => {
|
.afterStdTestConnection(async (context: Context, output: StdTestConnectionOutput) => {
|
||||||
@@ -48,4 +49,5 @@ Use this logic to implement the command:
|
|||||||
return output
|
return output
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
The output datatype is always an empty object handed down from the connector.
|
|
||||||
|
The output datatype is always an empty object handed down from the connector.
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ sail conn customizers init my-customizer-project
|
|||||||
|
|
||||||
The CLI init command creates a new folder with your project name in the location where you run the command.
|
The CLI init command creates a new folder with your project name in the location where you run the command.
|
||||||
|
|
||||||
Change the directory to the project folder and run ```npm install`` to install the dependencies.
|
Change the directory to the project folder and run ``npm install` to install the dependencies.
|
||||||
|
|
||||||
### Source files
|
### Source files
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Customizers
|
|||||||
sidebar_position: 7.1
|
sidebar_position: 7.1
|
||||||
sidebar_class_name: saasConnectivity
|
sidebar_class_name: saasConnectivity
|
||||||
keywords: ['connectivity', 'connectors', customizers]
|
keywords: ['connectivity', 'connectors', customizers]
|
||||||
description: Connectivity customizers can customize out of the box SaaS connectors.
|
description: Connectivity customizers can customize out of the box SaaS connectors.
|
||||||
slug: /connectivity/saas-connectivity/customizers
|
slug: /connectivity/saas-connectivity/customizers
|
||||||
tags: ['Connectivity']
|
tags: ['Connectivity']
|
||||||
---
|
---
|
||||||
@@ -17,9 +17,9 @@ SaaS Connectivity Customizers are cloud-based connector customizers that make cu
|
|||||||
|
|
||||||
## How do they work?
|
## How do they work?
|
||||||
|
|
||||||
SaaS Connectivity Customizers work by sitting in between Identity Security Cloud and the connector. They intercept calls from Identity Security Cloud to the connector and calls from the connector to Identity Security Cloud. When the customizer intercepts a call, it can call custom code to mutate the data in any way necessary to change the connector behavior.
|
SaaS Connectivity Customizers work by sitting in between Identity Security Cloud and the connector. They intercept calls from Identity Security Cloud to the connector and calls from the connector to Identity Security Cloud. When the customizer intercepts a call, it can call custom code to mutate the data in any way necessary to change the connector behavior.
|
||||||
|
|
||||||
This chart shows an example of this interception process - the ```stdAccountRead``` command is implemented with the customizer in place:
|
This chart shows an example of this interception process - the `stdAccountRead` command is implemented with the customizer in place:
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
@@ -37,4 +37,4 @@ sequenceDiagram
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Use this command to find sources:
|
|||||||
```bash
|
```bash
|
||||||
sail conn instances list
|
sail conn instances list
|
||||||
```
|
```
|
||||||
|
|
||||||
This similar looking list of instances will be returned:
|
This similar looking list of instances will be returned:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -41,6 +42,7 @@ Use this command to find customizers:
|
|||||||
```bash
|
```bash
|
||||||
sail conn customizers list
|
sail conn customizers list
|
||||||
```
|
```
|
||||||
|
|
||||||
This similar looking list of customizers will be returned:
|
This similar looking list of customizers will be returned:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -58,7 +60,9 @@ To link a source to a customizer, find the source ID in the instance list and a
|
|||||||
```bash
|
```bash
|
||||||
sail conn customizers link -i edfc9bfb-b55c-482f-b1aa-b4d51caf7558 -c 7b968fab-0f40-49f0-b13b-8bf529fc0b82
|
sail conn customizers link -i edfc9bfb-b55c-482f-b1aa-b4d51caf7558 -c 7b968fab-0f40-49f0-b13b-8bf529fc0b82
|
||||||
```
|
```
|
||||||
|
|
||||||
The output will indicate that the customizer has succesfully linked to the connector instance:
|
The output will indicate that the customizer has succesfully linked to the connector instance:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
+--------------------------------------+----------------------+--------------------------------------+
|
+--------------------------------------+----------------------+--------------------------------------+
|
||||||
| ID | NAME | CUSTOMIZER ID |
|
| ID | NAME | CUSTOMIZER ID |
|
||||||
@@ -69,7 +73,7 @@ The output will indicate that the customizer has succesfully linked to the conne
|
|||||||
|
|
||||||
### Unlink from a source
|
### Unlink from a source
|
||||||
|
|
||||||
To unlink a customizer from a source, issue the unlink command and pass the source instance ID:
|
To unlink a customizer from a source, issue the unlink command and pass the source instance ID:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sail conn customizers unlink -i edfc9bfb-b55c-482f-b1aa-b4d51caf7558
|
sail conn customizers unlink -i edfc9bfb-b55c-482f-b1aa-b4d51caf7558
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Testing and Debugging
|
|||||||
sidebar_position: 6
|
sidebar_position: 6
|
||||||
sidebar_class_name: saasConnectivity
|
sidebar_class_name: saasConnectivity
|
||||||
keywords: ['connectivity', 'connectors', customizers]
|
keywords: ['connectivity', 'connectors', customizers]
|
||||||
description: Test and debug connectors with customizers.
|
description: Test and debug connectors with customizers.
|
||||||
slug: /connectivity/saas-connectivity/customizers/testing
|
slug: /connectivity/saas-connectivity/customizers/testing
|
||||||
tags: ['Connectivity']
|
tags: ['Connectivity']
|
||||||
---
|
---
|
||||||
@@ -25,7 +25,7 @@ You can then set breakpoints in your code step through processes in your IDE (in
|
|||||||
|
|
||||||
### Test alongside a custom connector
|
### Test alongside a custom connector
|
||||||
|
|
||||||
If you want to test alongside a SaaS custom connector, the easiest way to do so is to copy the customizer code into the connector code.
|
If you want to test alongside a SaaS custom connector, the easiest way to do so is to copy the customizer code into the connector code.
|
||||||
|
|
||||||
For example, you want to test this connector:
|
For example, you want to test this connector:
|
||||||
|
|
||||||
@@ -80,4 +80,4 @@ export const connectorCustomizer = async () => {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, when you run the test-connection command, the customizer after the test-connection command will also run.
|
Now, when you run the test-connection command, the customizer after the test-connection command will also run.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Before you can upload a connector customizer, you must issue the create command
|
|||||||
sail conn customizers create my-connector-customizer
|
sail conn customizers create my-connector-customizer
|
||||||
```
|
```
|
||||||
|
|
||||||
This will return the customizer ID.
|
This will return the customizer ID.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
+--------------------------------------+-------------------------+---------+
|
+--------------------------------------+-------------------------+---------+
|
||||||
@@ -55,4 +55,5 @@ To upload the customizer to Identity Security Cloud, use the upload command:
|
|||||||
```bash
|
```bash
|
||||||
sail conn customizers upload -c 7b968fab-0f40-49f0-b13b-8bf529fc0b82 -f .\dist\my-connector-customizer-0.1.0.zip
|
sail conn customizers upload -c 7b968fab-0f40-49f0-b13b-8bf529fc0b82 -f .\dist\my-connector-customizer-0.1.0.zip
|
||||||
```
|
```
|
||||||
Now the customizer is ready to be used!
|
|
||||||
|
Now the customizer is ready to be used!
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ id: connector-spec-card
|
|||||||
title: Card
|
title: Card
|
||||||
pagination_label: Card
|
pagination_label: Card
|
||||||
sidebar_label: Card
|
sidebar_label: Card
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'card']
|
keywords: ['connectivity', 'connectors', 'connector-spec', 'card']
|
||||||
description: Details on using the card item
|
description: Details on using the card item
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/card
|
slug: /connectivity/saas-connectivity/connector-spec/card
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to use the card type in the connector spec
|
## How to use the card type in the connector spec
|
||||||
|
|
||||||
You can use the `card` type to specify cards that allow users to add/copy/delete and enter a subMenu to make changes to more card details.
|
You can use the `card` type to specify cards that allow users to add/copy/delete and enter a subMenu to make changes to more card details.
|
||||||
|
|
||||||
When you create a card, you must specify the fields the cardSubMenu will use to generate the title and subtitle, as shown in the following example.
|
When you create a card, you must specify the fields the cardSubMenu will use to generate the title and subtitle, as shown in the following example.
|
||||||
|
|
||||||
In this example, clicking the ```Add table``` button opens a dialog, and the values entered for the ```Table Information``` and ```Airtable Id``` will populate the cards ```title``` and ```subtitle```.
|
In this example, clicking the `Add table` button opens a dialog, and the values entered for the `Table Information` and `Airtable Id` will populate the cards `title` and `subtitle`.
|
||||||
|
|
||||||
### Example card item type
|
### Example card item type
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ In this example, clicking the ```Add table``` button opens a dialog, and the val
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ id: connector-spec-initial-value
|
|||||||
title: Initial Value
|
title: Initial Value
|
||||||
pagination_label: Initial Value
|
pagination_label: Initial Value
|
||||||
sidebar_label: Initial Value
|
sidebar_label: Initial Value
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'sourceConfigInitialValues']
|
keywords:
|
||||||
|
['connectivity', 'connectors', 'connector-spec', 'sourceConfigInitialValues']
|
||||||
description: How to use the sourceConfigInitialValues field
|
description: How to use the sourceConfigInitialValues field
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/initial-value
|
slug: /connectivity/saas-connectivity/connector-spec/initial-value
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
@@ -41,4 +42,4 @@ If you want to prepopulate a field in the connector spec configuration with an i
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ id: connector-spec-key-value
|
|||||||
title: Key Value
|
title: Key Value
|
||||||
pagination_label: Key Value
|
pagination_label: Key Value
|
||||||
sidebar_label: Key Value
|
sidebar_label: Key Value
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'keyValue']
|
keywords: ['connectivity', 'connectors', 'connector-spec', 'keyValue']
|
||||||
description: Details on using the key value item
|
description: Details on using the key value item
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/key-value
|
slug: /connectivity/saas-connectivity/connector-spec/key-value
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to use the key value type in the connector spec
|
## How to use the key value type in the connector spec
|
||||||
You can use the `keyValue` type to allow users to enter multiple key value items in a single entry box.
|
|
||||||
|
You can use the `keyValue` type to allow users to enter multiple key value items in a single entry box.
|
||||||
|
|
||||||
This is an example implementation:
|
This is an example implementation:
|
||||||
|
|
||||||
@@ -37,4 +38,5 @@ This is an example implementation:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -3,16 +3,17 @@ id: connector-spec-list
|
|||||||
title: List
|
title: List
|
||||||
pagination_label: List
|
pagination_label: List
|
||||||
sidebar_label: List
|
sidebar_label: List
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'list']
|
keywords: ['connectivity', 'connectors', 'connector-spec', 'list']
|
||||||
description: Details on using the list item
|
description: Details on using the list item
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/list
|
slug: /connectivity/saas-connectivity/connector-spec/list
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to use the list type in the connector spec
|
## How to use the list type in the connector spec
|
||||||
You can use the `list` type to allow users to enter multiple items in a single entry box.
|
|
||||||
|
|
||||||
This is an example implementation:
|
You can use the `list` type to allow users to enter multiple items in a single entry box.
|
||||||
|
|
||||||
|
This is an example implementation:
|
||||||
|
|
||||||
### Example list item type
|
### Example list item type
|
||||||
|
|
||||||
@@ -24,4 +25,5 @@ This is an example implementation:
|
|||||||
"helpKey": "Add a list of entitlements to expose via your source"
|
"helpKey": "Add a list of entitlements to expose via your source"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -3,14 +3,15 @@ id: connector-spec-radio
|
|||||||
title: Radio
|
title: Radio
|
||||||
pagination_label: Radio
|
pagination_label: Radio
|
||||||
sidebar_label: Radio
|
sidebar_label: Radio
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'radio']
|
keywords: ['connectivity', 'connectors', 'connector-spec', 'radio']
|
||||||
description: Details on using the Radio item
|
description: Details on using the Radio item
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/radio
|
slug: /connectivity/saas-connectivity/connector-spec/radio
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to use the radio type in the connector spec
|
## How to use the radio type in the connector spec
|
||||||
You can use the `Rrdio` type to create radio buttons for users to interact with to select from a predefined set of values.
|
|
||||||
|
You can use the `Rrdio` type to create radio buttons for users to interact with to select from a predefined set of values.
|
||||||
|
|
||||||
This is an example implementation:
|
This is an example implementation:
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ This is an example implementation:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You can also create dependencies on other fields so they are hidden until the selection is made. This same type of dependency can be built into any field and linked by using the parentKey/parentValue fields.
|
You can also create dependencies on other fields so they are hidden until the selection is made. This same type of dependency can be built into any field and linked by using the parentKey/parentValue fields.
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ id: connector-spec-select
|
|||||||
title: Select
|
title: Select
|
||||||
pagination_label: Select
|
pagination_label: Select
|
||||||
sidebar_label: Select
|
sidebar_label: Select
|
||||||
keywords: ['connectivity', 'connectors','connector-spec', 'select']
|
keywords: ['connectivity', 'connectors', 'connector-spec', 'select']
|
||||||
description: Details on using the select item
|
description: Details on using the select item
|
||||||
slug: /connectivity/saas-connectivity/connector-spec/select
|
slug: /connectivity/saas-connectivity/connector-spec/select
|
||||||
tags: ['Connectivity', 'Connector Spec']
|
tags: ['Connectivity', 'Connector Spec']
|
||||||
---
|
---
|
||||||
|
|
||||||
## How to use the Select type in the connector spec
|
## How to use the Select type in the connector spec
|
||||||
You can use the Select type to create a dropdown for users to interact with to select from a predefined set of values.
|
|
||||||
|
You can use the Select type to create a dropdown for users to interact with to select from a predefined set of values.
|
||||||
|
|
||||||
This is an example implementation:
|
This is an example implementation:
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ This is an example implementation:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You can also create dependencies on other fields so they are hidden until the selection is made. This same type of dependency can be built into any field and linked by using the parentKey/parentValue fields.
|
You can also create dependencies on other fields so they are hidden until the selection is made. This same type of dependency can be built into any field and linked by using the parentKey/parentValue fields.
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ slug: /connectivity/saas-connectivity/in-depth/cli-advanced
|
|||||||
tags: ['Connectivity']
|
tags: ['Connectivity']
|
||||||
---
|
---
|
||||||
|
|
||||||
You can use the CLI to invoke a number of calls in Identity Security Cloud, including calls that aren't specifically defined by the CLI. This section includes examples that show how you can invoke those calls:
|
You can use the CLI to invoke a number of calls in Identity Security Cloud, including calls that aren't specifically defined by the CLI. This section includes examples that show how you can invoke those calls:
|
||||||
|
|
||||||
## Use provided CLI invoke calls
|
## Use provided CLI invoke calls
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ Available Commands:
|
|||||||
source-data-read Invoke a std:source-data:read command
|
source-data-read Invoke a std:source-data:read command
|
||||||
test-connection Invoke a std:test-connection command
|
test-connection Invoke a std:test-connection command
|
||||||
```
|
```
|
||||||
|
|
||||||
To understand the required parameters to invoke a command from the CLI, you can use the help command to get a list of required parameters. For example, to read an account using the CLI, first call `sail conn invoke account-read -h`. The CLI will respond with the required input:
|
To understand the required parameters to invoke a command from the CLI, you can use the help command to get a list of required parameters. For example, to read an account using the CLI, first call `sail conn invoke account-read -h`. The CLI will respond with the required input:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -52,14 +53,15 @@ Global Flags:
|
|||||||
-c, --id string Connector ID or Alias
|
-c, --id string Connector ID or Alias
|
||||||
-v, --version string Optional. Run against a specific version if provided. Otherwise run against the latest tag.
|
-v, --version string Optional. Run against a specific version if provided. Otherwise run against the latest tag.
|
||||||
```
|
```
|
||||||
In this case, you need to provide the connector ID, the config path that contains the necessary configuration for the connector, and the ID for the account.
|
|
||||||
|
In this case, you need to provide the connector ID, the config path that contains the necessary configuration for the connector, and the ID for the account.
|
||||||
|
|
||||||
The config file will look something like this:
|
The config file will look something like this:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"apiKey": "<API_KEY>",
|
"apiKey": "<API_KEY>",
|
||||||
"airtableBase": "<BASE_ID>"
|
"airtableBase": "<BASE_ID>"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ sail conn invoke account-read philip.ellis -c 4b12cf79-b2ac-44ac-842b-b5a6268548
|
|||||||
|
|
||||||
## Use sail conn invoke raw
|
## Use sail conn invoke raw
|
||||||
|
|
||||||
Even if a command isn't supported by the CLI, you can still invoke it. The `invoke raw` command allows you to specify the entire JSON object used to invoke the command.
|
Even if a command isn't supported by the CLI, you can still invoke it. The `invoke raw` command allows you to specify the entire JSON object used to invoke the command.
|
||||||
|
|
||||||
You can use the Postman collection as a way to build the JSON object needed to invoke the command. For example, if you want to run the `account-disable` command, you can create a JSON object with the required fields. If you look at this example, you will see that it closely resembles the same information that is sent when debugging the command using Postman:
|
You can use the Postman collection as a way to build the JSON object needed to invoke the command. For example, if you want to run the `account-disable` command, you can create a JSON object with the required fields. If you look at this example, you will see that it closely resembles the same information that is sent when debugging the command using Postman:
|
||||||
|
|
||||||
@@ -83,6 +85,7 @@ You can use the Postman collection as a way to build the JSON object needed to i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Running the `raw` command is similar to running the other commands, except now you pass the JSON file created earlier with the `-f` flag:
|
Running the `raw` command is similar to running the other commands, except now you pass the JSON file created earlier with the `-f` flag:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ An Identity Security Cloud SaaS Connectivity connector will send a timeout error
|
|||||||
|
|
||||||
In the case of a long running API call to the source system, you can also optionally send `res.keepAlive()` to keep the connection to Identity Security Cloud open without having to send any data to Identity Security Cloud. If `res.keepAlive()` or `res.send()` is not called within 3 minutes, a connector timeout will occur.
|
In the case of a long running API call to the source system, you can also optionally send `res.keepAlive()` to keep the connection to Identity Security Cloud open without having to send any data to Identity Security Cloud. If `res.keepAlive()` or `res.send()` is not called within 3 minutes, a connector timeout will occur.
|
||||||
|
|
||||||
This is an example of how to set up this pagination:
|
This is an example of how to set up this pagination:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
async getAccounts(res: Response<StdAccountListOutput>): Promise<boolean> {
|
async getAccounts(res: Response<StdAccountListOutput>): Promise<boolean> {
|
||||||
@@ -25,7 +25,7 @@ async getAccounts(res: Response<StdAccountListOutput>): Promise<boolean> {
|
|||||||
// each page will be called recursively until there are no more records to fetch, at which case the promise is fulfilled
|
// each page will be called recursively until there are no more records to fetch, at which case the promise is fulfilled
|
||||||
).eachPage((records, fetchNextPage) => {
|
).eachPage((records, fetchNextPage) => {
|
||||||
for (let record of records) {
|
for (let record of records) {
|
||||||
// this is the part that sends the data to Identity Security Cloud. Since eachPage is called with just 10 records,
|
// this is the part that sends the data to Identity Security Cloud. Since eachPage is called with just 10 records,
|
||||||
// if there are 100 records total, we would send data back to ISC in 10 sets of 10 records.
|
// if there are 100 records total, we would send data back to ISC in 10 sets of 10 records.
|
||||||
res.send({
|
res.send({
|
||||||
identity: record.id,
|
identity: record.id,
|
||||||
|
|||||||
@@ -45,15 +45,15 @@ export class AirtableClient {
|
|||||||
|
|
||||||
## Not Found Error Type
|
## Not Found Error Type
|
||||||
|
|
||||||
The connector SDK offers a special error type of "Not Found". This error signals to ISC that the specific account is not in the source system. If the account should be in the source system, ISC will then call the connector ```std:account:create``` command to create the account.
|
The connector SDK offers a special error type of "Not Found". This error signals to ISC that the specific account is not in the source system. If the account should be in the source system, ISC will then call the connector `std:account:create` command to create the account.
|
||||||
|
|
||||||
Here is an example:
|
Here is an example:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
.stdAccountUpdate(async (context: Context, input: StdAccountUpdateInput, res: Response<StdAccountUpdateOutput>) => {
|
.stdAccountUpdate(async (context: Context, input: StdAccountUpdateInput, res: Response<StdAccountUpdateOutput>) => {
|
||||||
const account = await myClient.getAccount(input.identity)
|
const account = await myClient.getAccount(input.identity)
|
||||||
if (!account) {
|
if (!account) {
|
||||||
// account was not found, but identity now has the account and expects it to be there!
|
// account was not found, but identity now has the account and expects it to be there!
|
||||||
// Send an error message to Identity Security Cloud so the account is automatically created
|
// Send an error message to Identity Security Cloud so the account is automatically created
|
||||||
if (!account) {
|
if (!account) {
|
||||||
throw new ConnectorError("account is not found", ConnectorErrorType.NotFound)
|
throw new ConnectorError("account is not found", ConnectorErrorType.NotFound)
|
||||||
@@ -120,19 +120,25 @@ export class AirtableClient {
|
|||||||
## Recommended custom exceptions and examples of when to use them
|
## Recommended custom exceptions and examples of when to use them
|
||||||
|
|
||||||
#### InvalidConfigurationException
|
#### InvalidConfigurationException
|
||||||
|
|
||||||
- Use this exception during any operation if the connector requires a certain configuration to connect to the managed-system, but the configuration is either faulty or not provided. This could happen before sending a request to the managed system.
|
- Use this exception during any operation if the connector requires a certain configuration to connect to the managed-system, but the configuration is either faulty or not provided. This could happen before sending a request to the managed system.
|
||||||
|
|
||||||
#### InsufficientPermissionException
|
#### InsufficientPermissionException
|
||||||
- Use this exception during any operation if the connector gets a known managed system exception indicating a lack of permission.
|
|
||||||
|
- Use this exception during any operation if the connector gets a known managed system exception indicating a lack of permission.
|
||||||
|
|
||||||
#### InvalidRequestException
|
#### InvalidRequestException
|
||||||
|
|
||||||
- Use this exception during any operation if the connector is creating messages to be sent to the managed system but is failing to create a message. This could happen before sending a request to the managed system.
|
- Use this exception during any operation if the connector is creating messages to be sent to the managed system but is failing to create a message. This could happen before sending a request to the managed system.
|
||||||
|
|
||||||
#### ObjectAlreadyExistsException
|
#### ObjectAlreadyExistsException
|
||||||
|
|
||||||
- Use this exception during the provisioning operation of the type create(only) if the connector is trying to create an entity that already exists on the managed system.
|
- Use this exception during the provisioning operation of the type create(only) if the connector is trying to create an entity that already exists on the managed system.
|
||||||
|
|
||||||
#### InvalidResponseException
|
#### InvalidResponseException
|
||||||
|
|
||||||
- Use this exception during aggregation or in the getObject when the connector is unable to parse data received from managed system. This could happen if something fails when converting a managed system response to a ResourceObject.
|
- Use this exception during aggregation or in the getObject when the connector is unable to parse data received from managed system. This could happen if something fails when converting a managed system response to a ResourceObject.
|
||||||
|
|
||||||
#### TimeoutException
|
#### TimeoutException
|
||||||
- This is intended for cases in which the connector receives timeout related error/exceptions from the managed system.
|
|
||||||
|
- This is intended for cases in which the connector receives timeout related error/exceptions from the managed system.
|
||||||
|
|||||||
@@ -20,9 +20,10 @@ Connectors are the bridges between the SailPoint Identity Security Cloud (ISC) S
|
|||||||
## Why We Are Introducing SaaS Connectivity
|
## Why We Are Introducing SaaS Connectivity
|
||||||
|
|
||||||
The primary driver for indroducing the SaaS Connectivity framework is to allow a way to connect to other cloud based sources in a truly SaaS architecture, without the need to rely on a VA. There are also other benefits that come with the SaaS Connectivity framework:
|
The primary driver for indroducing the SaaS Connectivity framework is to allow a way to connect to other cloud based sources in a truly SaaS architecture, without the need to rely on a VA. There are also other benefits that come with the SaaS Connectivity framework:
|
||||||
- Ability to develop, debug and test custom connectors locally without any dependencies on Identity Security Cloud
|
|
||||||
- Features to customize the user interface when configuring the connector that are specific to the source
|
- Ability to develop, debug and test custom connectors locally without any dependencies on Identity Security Cloud
|
||||||
- Support for more modern languages and frameworks
|
- Features to customize the user interface when configuring the connector that are specific to the source
|
||||||
|
- Support for more modern languages and frameworks
|
||||||
|
|
||||||
## Architecture of SaaS Connectivity
|
## Architecture of SaaS Connectivity
|
||||||
|
|
||||||
@@ -42,4 +43,4 @@ With both SaaS connectivity and traditional VA connectivity in place, you can ha
|
|||||||
|
|
||||||
Any direct connectors that specify a virtual appliance (VA) use [Zero Knowledge Encryption](https://community.sailpoint.com/t5/Lighthouse/Protecting-Sensitive-Data-with-Zero-Knowledge-Encryption/ta-p/79657?attachment-id=452) schemes with an RSA 2048-bit asymmetric key pair: there is a private key on the VA for decryption and a public key in the cloud (as part of the VA cluster) for encryption.
|
Any direct connectors that specify a virtual appliance (VA) use [Zero Knowledge Encryption](https://community.sailpoint.com/t5/Lighthouse/Protecting-Sensitive-Data-with-Zero-Knowledge-Encryption/ta-p/79657?attachment-id=452) schemes with an RSA 2048-bit asymmetric key pair: there is a private key on the VA for decryption and a public key in the cloud (as part of the VA cluster) for encryption.
|
||||||
|
|
||||||
SaaS connectors cannot operate the same way because they do not communicate through VA clusters. Despite this, SaaS connectors can still leverage the asymmetric key pair scheme — the key pair simply resides in the cloud instead of on the VA. The key pair is only accessible to the Connectivity service and is managed to SailPoint standards for credential storage. Whenever you are storing secret data, use the ```secret``` or ```secrettextarea``` field types.
|
SaaS connectors cannot operate the same way because they do not communicate through VA clusters. Despite this, SaaS connectors can still leverage the asymmetric key pair scheme — the key pair simply resides in the cloud instead of on the VA. The key pair is only accessible to the Connectivity service and is managed to SailPoint standards for credential storage. Whenever you are storing secret data, use the `secret` or `secrettextarea` field types.
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ tags: ['Connectivity', 'Postman']
|
|||||||
Use the following Postman Collection file to run tests for each of the commands locally.
|
Use the following Postman Collection file to run tests for each of the commands locally.
|
||||||
|
|
||||||
| API | Postman Collection |
|
| API | Postman Collection |
|
||||||
|------|----------------------------|
|
| --- | --- |
|
||||||
| SaaS Connectivity | [](https://god.gw.postman.com/run-collection/23226990-a0b5c429-d8dd-4fe2-a4a2-eb7ff85322ef?action=collection%2Ffork&collection-url=entityId%3D23226990-a0b5c429-d8dd-4fe2-a4a2-eb7ff85322ef%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
| SaaS Connectivity | [](https://god.gw.postman.com/run-collection/23226990-a0b5c429-d8dd-4fe2-a4a2-eb7ff85322ef?action=collection%2Ffork&collection-url=entityId%3D23226990-a0b5c429-d8dd-4fe2-a4a2-eb7ff85322ef%26entityType%3Dcollection%26workspaceId%3D80af54be-a333-4712-af5e-41aa9eccbdd0) |
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ sail conn init my-first-project
|
|||||||
|
|
||||||
The CLI init command creates a new folder with your project name in the location where you run the command.
|
The CLI init command creates a new folder with your project name in the location where you run the command.
|
||||||
|
|
||||||
Change the directory to the project folder and run ```npm install to install`` the dependencies.
|
Change the directory to the project folder and run ``npm install to install` the dependencies.
|
||||||
|
|
||||||
### Source Files
|
### Source Files
|
||||||
|
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ $ sail conn tags list -c example-connector
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
Make sure that you implement a form of version control or regular backup process for your connectors.
|
Make sure that you implement a form of version control or regular backup process for your connectors. You cannot recover the source code from ISC because it gets sent to ISC as a compiled and minified JavaScript (JS) bundle that cannot be easily expanded into its original source code structure.
|
||||||
You cannot recover the source code from ISC because it gets sent to ISC as a compiled and minified JavaScript (JS) bundle that cannot be easily expanded into its original source code structure.
|
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,15 @@ description: Helpful videos on using SaaS connectivity
|
|||||||
slug: /connectivity/saas-connectivity/videos
|
slug: /connectivity/saas-connectivity/videos
|
||||||
tags: ['Connectivity']
|
tags: ['Connectivity']
|
||||||
---
|
---
|
||||||
|
|
||||||
import Video from '@site/src/components/Video';
|
import Video from '@site/src/components/Video';
|
||||||
|
|
||||||
## Videos
|
## Videos
|
||||||
|
|
||||||
During our 2023 Developer Days Conference, we created several connectivity videos. These videos can help you as you start building connectors:
|
During our 2023 Developer Days Conference, we created several connectivity videos. These videos can help you as you start building connectors:
|
||||||
|
|
||||||
- [Roadmap and Introduction](https://www.youtube.com/watch?v=12pfpLBNCvM)
|
- [Roadmap and Introduction](https://www.youtube.com/watch?v=12pfpLBNCvM)
|
||||||
- [Building a Complete Connector Walkthrough](https://www.youtube.com/watch?v=wHHje_ItTKQ)
|
- [Building a Complete Connector Walkthrough](https://www.youtube.com/watch?v=wHHje_ItTKQ)
|
||||||
- [SDKs in practice](https://www.youtube.com/watch?v=uvnlSUVsF8M)
|
- [SDKs in practice](https://www.youtube.com/watch?v=uvnlSUVsF8M)
|
||||||
|
|
||||||
<Video source="https://www.youtube.com/embed/wHHje_ItTKQ"></Video>
|
<Video source="https://www.youtube.com/embed/wHHje_ItTKQ"></Video>
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ sidebar_label: Extensibility
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: extensibility
|
sidebar_class_name: extensibility
|
||||||
keywords: ['extensibility']
|
keywords: ['extensibility']
|
||||||
description: Extend your ISC platform.
|
description: Extend your ISC platform.
|
||||||
slug: /extensibility
|
slug: /extensibility
|
||||||
tags: ['extensibility']
|
tags: ['extensibility']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
The Identity Security Cloud (ISC) platform is designed for extensibility, which means that it's designed to allow the addition of new capabilities or functionalities. In addition to the APIs, SailPoint provides a number of extensibility options you can use to build custom solutions and integrations that meet your organization's needs.
|
|
||||||
|
The Identity Security Cloud (ISC) platform is designed for extensibility, which means that it's designed to allow the addition of new capabilities or functionalities. In addition to the APIs, SailPoint provides a number of extensibility options you can use to build custom solutions and integrations that meet your organization's needs.
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
import DocCardList from '@theme/DocCardList';
|
import DocCardList from '@theme/DocCardList';
|
||||||
@@ -22,6 +23,7 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
|
||||||
|
|
||||||
To learn more about ISC extensibility and discuss the different extensibility options with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
|
To learn more about ISC extensibility and discuss the different extensibility options with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"customProps": {
|
"customProps": {
|
||||||
"description": "Export and import tenant configurations."
|
"description": "Export and import tenant configurations."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ pagination_label: Configuration Hub
|
|||||||
sidebar_position: 3
|
sidebar_position: 3
|
||||||
sidebar_class_name: configurationHub
|
sidebar_class_name: configurationHub
|
||||||
keywords: ['configuration']
|
keywords: ['configuration']
|
||||||
description: Manage tenant configurations with the ISC UI.
|
description: Manage tenant configurations with the ISC UI.
|
||||||
slug: /extensibility/configuration-management/configuration-hub
|
slug: /extensibility/configuration-management/configuration-hub
|
||||||
tags: ['Configuration', 'Hub']
|
tags: ['Configuration', 'Hub']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The SailPoint Configuration Hub supports management of configuration objects in your Identity Security Cloud (ISC) tenant through backup and deploy operations from the ISC UI. For example, you can back up configurations like sources and identity profiles defined for your business, restore them in the event of configuration errors or loss, or migrate and deploy them to your other tenants.
|
The SailPoint Configuration Hub supports management of configuration objects in your Identity Security Cloud (ISC) tenant through backup and deploy operations from the ISC UI. For example, you can back up configurations like sources and identity profiles defined for your business, restore them in the event of configuration errors or loss, or migrate and deploy them to your other tenants.
|
||||||
|
|
||||||
To learn more about Configuration Hub, refer to the [Configuration Hub documentation](https://documentation.sailpoint.com/saas/help/confighub/config_hub.html).
|
To learn more about Configuration Hub, refer to the [Configuration Hub documentation](https://documentation.sailpoint.com/saas/help/confighub/config_hub.html).
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
|
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
To learn more about the SaiLPoint Configuration Hub and discuss it with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
To learn more about the SaiLPoint Configuration Hub and discuss it with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"customProps": {
|
"customProps": {
|
||||||
"description": "Actions triggered by specific events."
|
"description": "Actions triggered by specific events."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,16 @@ title: Access Request Submitted
|
|||||||
pagination_label: Access Request Submitted
|
pagination_label: Access Request Submitted
|
||||||
sidebar_label: Access Request Submitted
|
sidebar_label: Access Request Submitted
|
||||||
sidebar_class_name: accessRequestSubmitted
|
sidebar_class_name: accessRequestSubmitted
|
||||||
keywords: ['event', 'trigger', 'access', 'request', 'submitted', 'preapproval', 'available']
|
keywords:
|
||||||
|
[
|
||||||
|
'event',
|
||||||
|
'trigger',
|
||||||
|
'access',
|
||||||
|
'request',
|
||||||
|
'submitted',
|
||||||
|
'preapproval',
|
||||||
|
'available',
|
||||||
|
]
|
||||||
description: Fires after an access request is submitted.
|
description: Fires after an access request is submitted.
|
||||||
slug: /extensibility/event-triggers/triggers/access-request-submitted
|
slug: /extensibility/event-triggers/triggers/access-request-submitted
|
||||||
tags: ['Event Triggers', 'Available Event Triggers', 'Request Response']
|
tags: ['Event Triggers', 'Available Event Triggers', 'Request Response']
|
||||||
|
|||||||
@@ -12,8 +12,7 @@ tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
|||||||
|
|
||||||
## Event Context
|
## Event Context
|
||||||
|
|
||||||
This event is triggered when a certification is signed-off and moves to End status.
|
This event is triggered when a certification is signed-off and moves to End status. This is not to be confused with Campaign End/Expiration.
|
||||||
This is not to be confused with Campaign End/Expiration.
|
|
||||||
|
|
||||||
This is an example input from this trigger:
|
This is an example input from this trigger:
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
|||||||
|
|
||||||
:::info Important Setup Steps
|
:::info Important Setup Steps
|
||||||
|
|
||||||
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
||||||
|
|
||||||
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
||||||
2. Configure the NCD options on the source in the source configuration UI.
|
2. Configure the NCD options on the source in the source configuration UI.
|
||||||
@@ -38,7 +38,7 @@ flowchart TD
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
This event trigger can be used to immediately notify interested parties and remediate accounts that are created directly on the source. Some examples of how this trigger can be used are as follows:
|
This event trigger can be used to immediately notify interested parties and remediate accounts that are created directly on the source. Some examples of how this trigger can be used are as follows:
|
||||||
|
|
||||||
- Notify the identity's manager and the source owner of the new account
|
- Notify the identity's manager and the source owner of the new account
|
||||||
- Create a micro-certification for the identity to review their new account access
|
- Create a micro-certification for the identity to review their new account access
|
||||||
@@ -48,139 +48,131 @@ This is an example input from this trigger:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"identity": {
|
"identity": {
|
||||||
"manager": {
|
"manager": {
|
||||||
"name": "Martena Heath",
|
"name": "Martena Heath",
|
||||||
"id": "2c91808378eb9fa30178fb8caf90097f",
|
"id": "2c91808378eb9fa30178fb8caf90097f",
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"email": "martena.heath@sample_email.com"
|
"email": "martena.heath@sample_email.com"
|
||||||
},
|
|
||||||
"name": "peter.williams",
|
|
||||||
"alias": "peter.williams",
|
|
||||||
"id": "e43ba47b265b4baf943efe3aaef886c8",
|
|
||||||
"type": "IDENTITY",
|
|
||||||
"email": "peter.williams@sample_email.com"
|
|
||||||
},
|
},
|
||||||
"singleValueAttributeChanges": [
|
"name": "peter.williams",
|
||||||
{
|
"alias": "peter.williams",
|
||||||
"newValue": "Peter Williams",
|
"id": "e43ba47b265b4baf943efe3aaef886c8",
|
||||||
"name": "cn",
|
"type": "IDENTITY",
|
||||||
"oldValue": null
|
"email": "peter.williams@sample_email.com"
|
||||||
},
|
},
|
||||||
{
|
"singleValueAttributeChanges": [
|
||||||
"newValue": "Peter Williams",
|
{
|
||||||
"name": "displayName",
|
"newValue": "Peter Williams",
|
||||||
"oldValue": null
|
"name": "cn",
|
||||||
},
|
"oldValue": null
|
||||||
{
|
|
||||||
"newValue": "CN=Peter Williams,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com",
|
|
||||||
"name": "distinguishedName",
|
|
||||||
"oldValue": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"newValue": "Peter",
|
|
||||||
"name": "givenName",
|
|
||||||
"oldValue": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"entitlementChanges": [
|
|
||||||
{
|
|
||||||
"removed": [],
|
|
||||||
"added": [
|
|
||||||
{
|
|
||||||
"owner": {
|
|
||||||
"id": "2c91808978eb9fab0178fb8ca9280919",
|
|
||||||
"name": "Gregory Brooks",
|
|
||||||
"type": "IDENTITY"
|
|
||||||
},
|
|
||||||
"name": "ProductionManagement",
|
|
||||||
"id": "2c91808778eb9fa30178fb9482f00c60",
|
|
||||||
"value": "CN=ProductionManagement,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"owner": null,
|
|
||||||
"name": "Employees",
|
|
||||||
"id": "2c91808378eb9fa30178fb94818e0af8",
|
|
||||||
"value": "CN=Employees,OU=BirthRight,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"owner": null,
|
|
||||||
"name": "WindowsAdministration",
|
|
||||||
"id": "2c91808378eb9fa30178fb9481c30b02",
|
|
||||||
"value": "CN=WindowsAdministration,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"attributeName": "memberOf"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"eventType": "ACCOUNT_CREATED",
|
|
||||||
"source": {
|
|
||||||
"owner": {
|
|
||||||
"name": "Aaron Andrew",
|
|
||||||
"id": "2c9180867a7c46d0017a7ca099d50531",
|
|
||||||
"type": "IDENTITY",
|
|
||||||
"email": "aaron.andrew@sample_email.com"
|
|
||||||
},
|
|
||||||
"name": "Active Directory",
|
|
||||||
"alias": "Active Directory [source]",
|
|
||||||
"id": "2c91808a78efc63e0178fb8624b248c5",
|
|
||||||
"type": "SOURCE",
|
|
||||||
"governanceGroup": {
|
|
||||||
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
|
||||||
"name": "Active Directory Owners",
|
|
||||||
"type": "GOVERNANCE_GROUP"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"accountChangeTypes": [
|
{
|
||||||
"ATTRIBUTES_CHANGED",
|
"newValue": "Peter Williams",
|
||||||
"ENTITLEMENTS_ADDED"
|
"name": "displayName",
|
||||||
],
|
"oldValue": null
|
||||||
"multiValueAttributeChanges": [
|
},
|
||||||
{
|
{
|
||||||
"removedValues": [],
|
"newValue": "CN=Peter Williams,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com",
|
||||||
"addedValues": [
|
"name": "distinguishedName",
|
||||||
"top",
|
"oldValue": null
|
||||||
"person",
|
},
|
||||||
"organizationalPerson",
|
{
|
||||||
"user"
|
"newValue": "Peter",
|
||||||
],
|
"name": "givenName",
|
||||||
"name": "objectClass"
|
"oldValue": null
|
||||||
},
|
|
||||||
{
|
|
||||||
"removedValues": [],
|
|
||||||
"addedValues": [
|
|
||||||
"Normal User Account",
|
|
||||||
"Password Cannot Expire",
|
|
||||||
"User Account is Disabled"
|
|
||||||
],
|
|
||||||
"name": "accountFlags"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"account": {
|
|
||||||
"name": "peter.williams",
|
|
||||||
"id": "b3b17b0072f04da39b41e8802aaff01b",
|
|
||||||
"type": "ACCOUNT",
|
|
||||||
"uuid": "{615ebfa6-3d21-484e-9e67-01bd4e20c3da}",
|
|
||||||
"correlated": true,
|
|
||||||
"nativeIdentity": "CN=Peter Williams,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"entitlementChanges": [
|
||||||
|
{
|
||||||
|
"removed": [],
|
||||||
|
"added": [
|
||||||
|
{
|
||||||
|
"owner": {
|
||||||
|
"id": "2c91808978eb9fab0178fb8ca9280919",
|
||||||
|
"name": "Gregory Brooks",
|
||||||
|
"type": "IDENTITY"
|
||||||
|
},
|
||||||
|
"name": "ProductionManagement",
|
||||||
|
"id": "2c91808778eb9fa30178fb9482f00c60",
|
||||||
|
"value": "CN=ProductionManagement,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"owner": null,
|
||||||
|
"name": "Employees",
|
||||||
|
"id": "2c91808378eb9fa30178fb94818e0af8",
|
||||||
|
"value": "CN=Employees,OU=BirthRight,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"owner": null,
|
||||||
|
"name": "WindowsAdministration",
|
||||||
|
"id": "2c91808378eb9fa30178fb9481c30b02",
|
||||||
|
"value": "CN=WindowsAdministration,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"attributeName": "memberOf"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"eventType": "ACCOUNT_CREATED",
|
||||||
|
"source": {
|
||||||
|
"owner": {
|
||||||
|
"name": "Aaron Andrew",
|
||||||
|
"id": "2c9180867a7c46d0017a7ca099d50531",
|
||||||
|
"type": "IDENTITY",
|
||||||
|
"email": "aaron.andrew@sample_email.com"
|
||||||
|
},
|
||||||
|
"name": "Active Directory",
|
||||||
|
"alias": "Active Directory [source]",
|
||||||
|
"id": "2c91808a78efc63e0178fb8624b248c5",
|
||||||
|
"type": "SOURCE",
|
||||||
|
"governanceGroup": {
|
||||||
|
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
||||||
|
"name": "Active Directory Owners",
|
||||||
|
"type": "GOVERNANCE_GROUP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"accountChangeTypes": ["ATTRIBUTES_CHANGED", "ENTITLEMENTS_ADDED"],
|
||||||
|
"multiValueAttributeChanges": [
|
||||||
|
{
|
||||||
|
"removedValues": [],
|
||||||
|
"addedValues": ["top", "person", "organizationalPerson", "user"],
|
||||||
|
"name": "objectClass"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"removedValues": [],
|
||||||
|
"addedValues": [
|
||||||
|
"Normal User Account",
|
||||||
|
"Password Cannot Expire",
|
||||||
|
"User Account is Disabled"
|
||||||
|
],
|
||||||
|
"name": "accountFlags"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"account": {
|
||||||
|
"name": "peter.williams",
|
||||||
|
"id": "b3b17b0072f04da39b41e8802aaff01b",
|
||||||
|
"type": "ACCOUNT",
|
||||||
|
"uuid": "{615ebfa6-3d21-484e-9e67-01bd4e20c3da}",
|
||||||
|
"correlated": true,
|
||||||
|
"nativeIdentity": "CN=Peter Williams,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
||||||
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account created event, all aggregated account attributes will be listed, and their `oldValue` will be null.
|
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account created event, all aggregated account attributes will be listed, and their `oldValue` will be null.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `entitlementChanges` Contains a list of entitlements that have been aggregated with the account. the `removed` list will always be empty for an account created event.
|
- `entitlementChanges` Contains a list of entitlements that have been aggregated with the account. the `removed` list will always be empty for an account created event.
|
||||||
- `eventType` Will always be `ACCOUNT_CREATED` for account created events.
|
- `eventType` Will always be `ACCOUNT_CREATED` for account created events.
|
||||||
- `source` The source where this account originated from.
|
- `source` The source where this account originated from.
|
||||||
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
||||||
- Possible values are `ATTRIBUTES_CHANGED` and `ENTITLEMENTS_ADDED`.
|
- Possible values are `ATTRIBUTES_CHANGED` and `ENTITLEMENTS_ADDED`.
|
||||||
- The above example lists both change types since both attributes and entitlements were added. If an event payload only contains attributes added, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
- The above example lists both change types since both attributes and entitlements were added. If an event payload only contains attributes added, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
||||||
- `multiValueAttributeChanges` List of multivalued attributes that were aggregated with the account. Only `addedValues` will appear for account created events.
|
- `multiValueAttributeChanges` List of multivalued attributes that were aggregated with the account. Only `addedValues` will appear for account created events.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
||||||
|
|
||||||
## Additional Information and Links
|
## Additional Information and Links
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
|||||||
|
|
||||||
:::info Important Setup Steps
|
:::info Important Setup Steps
|
||||||
|
|
||||||
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
||||||
|
|
||||||
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
||||||
2. Configure the NCD options on the source in the source configuration UI.
|
2. Configure the NCD options on the source in the source configuration UI.
|
||||||
@@ -38,7 +38,7 @@ flowchart TD
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
This event trigger can be used to immediately notify interested parties and remediate accounts that are deleted directly on the source. Some examples of how this trigger can be used are as follows:
|
This event trigger can be used to immediately notify interested parties and remediate accounts that are deleted directly on the source. Some examples of how this trigger can be used are as follows:
|
||||||
|
|
||||||
- Notify the identity's manager and the source owner of the deleted account
|
- Notify the identity's manager and the source owner of the deleted account
|
||||||
|
|
||||||
@@ -46,129 +46,126 @@ This is an example input from this trigger:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"identity": {
|
"identity": {
|
||||||
"manager": {
|
"manager": {
|
||||||
"name": "Martena Heath",
|
"name": "Martena Heath",
|
||||||
"id": "2c91808378eb9fa30178fb8caf90097f",
|
"id": "2c91808378eb9fa30178fb8caf90097f",
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"email": "martena.heath@sample_email.com"
|
"email": "martena.heath@sample_email.com"
|
||||||
},
|
},
|
||||||
"name": "Letty Wilson",
|
"name": "Letty Wilson",
|
||||||
"alias": "Letty.Wilson",
|
"alias": "Letty.Wilson",
|
||||||
"id": "2c91808978eb9fab0178fb8ca6d308fb",
|
"id": "2c91808978eb9fab0178fb8ca6d308fb",
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"email": "letty.wilson@sample_email.com"
|
"email": "letty.wilson@sample_email.com"
|
||||||
},
|
},
|
||||||
"singleValueAttributeChanges": [{
|
"singleValueAttributeChanges": [
|
||||||
"newValue": null,
|
{
|
||||||
"name": "cn",
|
"newValue": null,
|
||||||
"oldValue": "Letty Wilson"
|
"name": "cn",
|
||||||
},
|
"oldValue": "Letty Wilson"
|
||||||
{
|
},
|
||||||
"newValue": null,
|
{
|
||||||
"name": "displayName",
|
"newValue": null,
|
||||||
"oldValue": "Letty Wilson"
|
"name": "displayName",
|
||||||
},
|
"oldValue": "Letty Wilson"
|
||||||
{
|
},
|
||||||
"newValue": null,
|
{
|
||||||
"name": "distinguishedName",
|
"newValue": null,
|
||||||
"oldValue": "CN=Letty Wilson,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
"name": "distinguishedName",
|
||||||
}
|
"oldValue": "CN=Letty Wilson,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
],
|
}
|
||||||
"entitlementChanges": [{
|
],
|
||||||
"removed": [{
|
"entitlementChanges": [
|
||||||
"owner": {
|
{
|
||||||
"id": "2c91808978eb9fab0178fb8ca9280919",
|
"removed": [
|
||||||
"name": "Gregory Brooks",
|
{
|
||||||
"type": "IDENTITY"
|
"owner": {
|
||||||
},
|
"id": "2c91808978eb9fab0178fb8ca9280919",
|
||||||
"name": "ProductionManagement",
|
"name": "Gregory Brooks",
|
||||||
"id": "2c91808778eb9fa30178fb9482f00c60",
|
"type": "IDENTITY"
|
||||||
"value": "CN=ProductionManagement,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
},
|
||||||
},
|
"name": "ProductionManagement",
|
||||||
{
|
"id": "2c91808778eb9fa30178fb9482f00c60",
|
||||||
"owner": null,
|
"value": "CN=ProductionManagement,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"name": "Employees",
|
},
|
||||||
"id": "2c91808378eb9fa30178fb94818e0af8",
|
{
|
||||||
"value": "CN=Employees,OU=BirthRight,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
"owner": null,
|
||||||
},
|
"name": "Employees",
|
||||||
{
|
"id": "2c91808378eb9fa30178fb94818e0af8",
|
||||||
"owner": null,
|
"value": "CN=Employees,OU=BirthRight,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"name": "WindowsAdministration",
|
},
|
||||||
"id": "2c91808378eb9fa30178fb9481c30b02",
|
{
|
||||||
"value": "CN=WindowsAdministration,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
"owner": null,
|
||||||
}
|
"name": "WindowsAdministration",
|
||||||
],
|
"id": "2c91808378eb9fa30178fb9481c30b02",
|
||||||
"added": [],
|
"value": "CN=WindowsAdministration,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"attributeName": "memberOf"
|
}
|
||||||
}],
|
],
|
||||||
"eventType": "ACCOUNT_DELETED",
|
"added": [],
|
||||||
"source": {
|
"attributeName": "memberOf"
|
||||||
"owner": {
|
}
|
||||||
"name": "Aaron Andrew",
|
],
|
||||||
"id": "2c9180867a7c46d0017a7ca099d50531",
|
"eventType": "ACCOUNT_DELETED",
|
||||||
"type": "IDENTITY",
|
"source": {
|
||||||
"email": "aaron.andrew@sample_email.com"
|
"owner": {
|
||||||
},
|
"name": "Aaron Andrew",
|
||||||
"name": "Active Directory",
|
"id": "2c9180867a7c46d0017a7ca099d50531",
|
||||||
"alias": "Active Directory [source]",
|
"type": "IDENTITY",
|
||||||
"id": "2c91808a78efc63e0178fb8624b248c5",
|
"email": "aaron.andrew@sample_email.com"
|
||||||
"type": "SOURCE",
|
},
|
||||||
"governanceGroup": {
|
"name": "Active Directory",
|
||||||
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
"alias": "Active Directory [source]",
|
||||||
"name": "Active Directory Owners",
|
"id": "2c91808a78efc63e0178fb8624b248c5",
|
||||||
"type": "GOVERNANCE_GROUP"
|
"type": "SOURCE",
|
||||||
}
|
"governanceGroup": {
|
||||||
},
|
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
||||||
"accountChangeTypes": [
|
"name": "Active Directory Owners",
|
||||||
"ATTRIBUTES_CHANGED",
|
"type": "GOVERNANCE_GROUP"
|
||||||
"ENTITLEMENTS_REMOVED"
|
}
|
||||||
],
|
},
|
||||||
"multiValueAttributeChanges": [{
|
"accountChangeTypes": ["ATTRIBUTES_CHANGED", "ENTITLEMENTS_REMOVED"],
|
||||||
"removedValues": [
|
"multiValueAttributeChanges": [
|
||||||
"top",
|
{
|
||||||
"person",
|
"removedValues": ["top", "person", "organizationalPerson", "user"],
|
||||||
"organizationalPerson",
|
"addedValues": [],
|
||||||
"user"
|
"name": "objectClass"
|
||||||
],
|
},
|
||||||
"addedValues": [],
|
{
|
||||||
"name": "objectClass"
|
"removedValues": [
|
||||||
},
|
"Normal User Account",
|
||||||
{
|
"Password Cannot Expire",
|
||||||
"removedValues": [
|
"User Account is Disabled"
|
||||||
"Normal User Account",
|
],
|
||||||
"Password Cannot Expire",
|
"addedValues": [],
|
||||||
"User Account is Disabled"
|
"name": "accountFlags"
|
||||||
],
|
}
|
||||||
"addedValues": [],
|
],
|
||||||
"name": "accountFlags"
|
"account": {
|
||||||
}
|
"name": "letty.wilson",
|
||||||
],
|
"id": "6805a47c09cc4dfca9083f1ce84552ee",
|
||||||
"account": {
|
"type": "ACCOUNT",
|
||||||
"name": "letty.wilson",
|
"uuid": "{3c096158-9188-46f4-bb13-20ef9daafa7f}",
|
||||||
"id": "6805a47c09cc4dfca9083f1ce84552ee",
|
"correlated": true,
|
||||||
"type": "ACCOUNT",
|
"nativeIdentity": "CN=Letty Wilson,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"uuid": "{3c096158-9188-46f4-bb13-20ef9daafa7f}",
|
}
|
||||||
"correlated": true,
|
|
||||||
"nativeIdentity": "CN=Letty Wilson,OU=Austin,OU=Americas,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
||||||
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account deleted event, all aggregated account attributes will be listed, and their `newValue` will be null.
|
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account deleted event, all aggregated account attributes will be listed, and their `newValue` will be null.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `entitlementChanges` Contains a list of entitlements that have been aggregated with the account. the `added` list will always be empty for an account deleted event.
|
- `entitlementChanges` Contains a list of entitlements that have been aggregated with the account. the `added` list will always be empty for an account deleted event.
|
||||||
- `eventType` Will always be `ACCOUNT_DELETED` for account deleted events.
|
- `eventType` Will always be `ACCOUNT_DELETED` for account deleted events.
|
||||||
- `source` The source where this account originated from.
|
- `source` The source where this account originated from.
|
||||||
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
||||||
- Possible values are `ATTRIBUTES_CHANGED` and `ENTITLEMENTS_REMOVED`.
|
- Possible values are `ATTRIBUTES_CHANGED` and `ENTITLEMENTS_REMOVED`.
|
||||||
- The above example lists both change types since both attributes and entitlements were removed. If an event payload only contains attributes removed, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
- The above example lists both change types since both attributes and entitlements were removed. If an event payload only contains attributes removed, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
||||||
- `multiValueAttributeChanges` List of multivalued attributes that were aggregated with the account. Only `removedValues` will appear for account deleted events.
|
- `multiValueAttributeChanges` List of multivalued attributes that were aggregated with the account. Only `removedValues` will appear for account deleted events.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
||||||
|
|
||||||
## Additional Information and Links
|
## Additional Information and Links
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
|||||||
|
|
||||||
:::info Important Setup Steps
|
:::info Important Setup Steps
|
||||||
|
|
||||||
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
You must have at least one source configured for Native Change Detection (NCD) before you will receive events from this trigger. There are two ways you can configure a source for NCD:
|
||||||
|
|
||||||
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
1. Invoke the [update native change detection configuration](https://developer.sailpoint.com/docs/api/beta/put-native-change-detection-config) for each source you want to receive events for NCD.
|
||||||
2. Configure the NCD options on the source in the source configuration UI.
|
2. Configure the NCD options on the source in the source configuration UI.
|
||||||
@@ -38,7 +38,7 @@ flowchart TD
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
This event trigger can be used to immediately notify interested parties and remediate accounts that are updated directly on the source. Some examples of how this trigger can be used are as follows:
|
This event trigger can be used to immediately notify interested parties and remediate accounts that are updated directly on the source. Some examples of how this trigger can be used are as follows:
|
||||||
|
|
||||||
- Notify the identity's manager and the source owner of the new account
|
- Notify the identity's manager and the source owner of the new account
|
||||||
- Create a micro-certification for the identity to review their new account attributes and entitlements
|
- Create a micro-certification for the identity to review their new account attributes and entitlements
|
||||||
@@ -48,82 +48,90 @@ This is an example input from this trigger:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"identity": {
|
"identity": {
|
||||||
"manager": {
|
"manager": {
|
||||||
"name": "Martena Heath",
|
"name": "Martena Heath",
|
||||||
"id": "2c91808378eb9fa30178fb8caf90097f",
|
"id": "2c91808378eb9fa30178fb8caf90097f",
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"email": "martena.heath@sample_email.com"
|
"email": "martena.heath@sample_email.com"
|
||||||
},
|
},
|
||||||
"name": "Ann English",
|
"name": "Ann English",
|
||||||
"alias": "Ann.English",
|
"alias": "Ann.English",
|
||||||
"id": "2c91808978eb9fab0178fb8ca6d308fb",
|
"id": "2c91808978eb9fab0178fb8ca6d308fb",
|
||||||
"type": "IDENTITY",
|
"type": "IDENTITY",
|
||||||
"email": "ann.english@sample_email.com"
|
"email": "ann.english@sample_email.com"
|
||||||
},
|
},
|
||||||
"singleValueAttributeChanges": [{
|
"singleValueAttributeChanges": [
|
||||||
"newValue": "Call Center Representative",
|
{
|
||||||
"name": "title",
|
"newValue": "Call Center Representative",
|
||||||
"oldValue": "Call Center Manager"
|
"name": "title",
|
||||||
}],
|
"oldValue": "Call Center Manager"
|
||||||
"entitlementChanges": [{
|
}
|
||||||
"removed": [{
|
],
|
||||||
"owner": null,
|
"entitlementChanges": [
|
||||||
"name": "AccountsReceivable",
|
{
|
||||||
"id": "d0470502d73d4c2e8c7543c712f518ca",
|
"removed": [
|
||||||
"value": "CN=AccountsReceivable,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
{
|
||||||
}],
|
"owner": null,
|
||||||
"added": [{
|
"name": "AccountsReceivable",
|
||||||
"owner": null,
|
"id": "d0470502d73d4c2e8c7543c712f518ca",
|
||||||
"name": "Accounts Payable",
|
"value": "CN=AccountsReceivable,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"id": "2c91808978eb9fab0178fb9482620b71",
|
}
|
||||||
"value": "CN=AccountsPayable,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
],
|
||||||
}],
|
"added": [
|
||||||
"attributeName": "memberOf"
|
{
|
||||||
}],
|
"owner": null,
|
||||||
"eventType": "ACCOUNT_UPDATED",
|
"name": "Accounts Payable",
|
||||||
"source": {
|
"id": "2c91808978eb9fab0178fb9482620b71",
|
||||||
"owner": {
|
"value": "CN=AccountsPayable,OU=Groups,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
"name": "Aaron Andrew",
|
}
|
||||||
"id": "2c9180867a7c46d0017a7ca099d50531",
|
],
|
||||||
"type": "IDENTITY",
|
"attributeName": "memberOf"
|
||||||
"email": "aaron.andrew@sample_email.com"
|
}
|
||||||
},
|
],
|
||||||
"name": "Active Directory",
|
"eventType": "ACCOUNT_UPDATED",
|
||||||
"alias": "Active Directory [source]",
|
"source": {
|
||||||
"id": "2c91808a78efc63e0178fb8624b248c5",
|
"owner": {
|
||||||
"type": "SOURCE",
|
"name": "Aaron Andrew",
|
||||||
"governanceGroup": {
|
"id": "2c9180867a7c46d0017a7ca099d50531",
|
||||||
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
"type": "IDENTITY",
|
||||||
"name": "Active Directory Owners",
|
"email": "aaron.andrew@sample_email.com"
|
||||||
"type": "GOVERNANCE_GROUP"
|
},
|
||||||
}
|
"name": "Active Directory",
|
||||||
},
|
"alias": "Active Directory [source]",
|
||||||
"accountChangeTypes": [
|
"id": "2c91808a78efc63e0178fb8624b248c5",
|
||||||
"ATTRIBUTES_CHANGED",
|
"type": "SOURCE",
|
||||||
"ENTITLEMENTS_ADDED",
|
"governanceGroup": {
|
||||||
"ENTITLEMENTS_REMOVED"
|
"id": "fd0d1393-35fb-47d8-9809-0e385b73f25e",
|
||||||
],
|
"name": "Active Directory Owners",
|
||||||
"multiValueAttributeChanges": [{
|
"type": "GOVERNANCE_GROUP"
|
||||||
"removedValues": [],
|
}
|
||||||
"addedValues": [
|
},
|
||||||
"User Account is Disabled"
|
"accountChangeTypes": [
|
||||||
],
|
"ATTRIBUTES_CHANGED",
|
||||||
"name": "accountFlags"
|
"ENTITLEMENTS_ADDED",
|
||||||
}],
|
"ENTITLEMENTS_REMOVED"
|
||||||
"account": {
|
],
|
||||||
"name": "Ann.English",
|
"multiValueAttributeChanges": [
|
||||||
"id": "2c91808378eb9fa30178fb9481a30afa",
|
{
|
||||||
"type": "ACCOUNT",
|
"removedValues": [],
|
||||||
"uuid": "{08ee6c6d-7d02-4978-9417-d92ba6a5ed50}",
|
"addedValues": ["User Account is Disabled"],
|
||||||
"correlated": true,
|
"name": "accountFlags"
|
||||||
"nativeIdentity": "CN=Ann English,OU=Call Center,OU=AI,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
}
|
||||||
}
|
],
|
||||||
|
"account": {
|
||||||
|
"name": "Ann.English",
|
||||||
|
"id": "2c91808378eb9fa30178fb9481a30afa",
|
||||||
|
"type": "ACCOUNT",
|
||||||
|
"uuid": "{08ee6c6d-7d02-4978-9417-d92ba6a5ed50}",
|
||||||
|
"correlated": true,
|
||||||
|
"nativeIdentity": "CN=Ann English,OU=Call Center,OU=AI,OU=Demo,DC=seri,DC=sailpointdemo,DC=com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
- `identity` The identity correlated to this account. If `account.correlated` is `false`, then this will be a system generated identity, not a real identity. For uncorrelated accounts, this system generated identity can be used to revoke entitlements on the account, or in any other API request that requires an identity ID.
|
||||||
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account updated event, only account attributes that were modified will be listed, and their `oldValue` will contain the previous value before the change.
|
- `singleValueAttributeChanges` Contains a list of account attributes that have changed. During an account updated event, only account attributes that were modified will be listed, and their `oldValue` will contain the previous value before the change.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `entitlementChanges` Contains a list of entitlements that have been added and/or removed on the account.
|
- `entitlementChanges` Contains a list of entitlements that have been added and/or removed on the account.
|
||||||
@@ -131,11 +139,11 @@ This is an example input from this trigger:
|
|||||||
- `source` The source where this account originated from.
|
- `source` The source where this account originated from.
|
||||||
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
- `accountChangeTypes` A list of change types you can expect to see in the event input.
|
||||||
- Possible values are `ATTRIBUTES_CHANGED`, `ENTITLEMENTS_ADDED`, and `ENTITLEMENTS_REMOVED`.
|
- Possible values are `ATTRIBUTES_CHANGED`, `ENTITLEMENTS_ADDED`, and `ENTITLEMENTS_REMOVED`.
|
||||||
- The above example lists all three change types since attributes were changed and entitlements were added and removed. If an event payload only contains changed attributes, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
- The above example lists all three change types since attributes were changed and entitlements were added and removed. If an event payload only contains changed attributes, then this list will only contain the `ATTRIBUTES_CHANGED` value. This can be useful when filtering events based on change types, or quickly checking what types of objects changed in the account before continuing to process the input.
|
||||||
- `multiValueAttributeChanges` List of multivalued attributes that were added and/or removed on the account.
|
- `multiValueAttributeChanges` List of multivalued attributes that were added and/or removed on the account.
|
||||||
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
- it will include ALL account attributes if the config is `"allNonEntitlementAttributes": true`
|
||||||
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
- it will include the enumerated list of attributes contained in `"selectedNonEntitlementAttributes": []`
|
||||||
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
- `account` The details of the account as it appears in Identity Security Cloud. This information can be used to query the account API for more information.
|
||||||
|
|
||||||
## Additional Information and Links
|
## Additional Information and Links
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ title: Outlier Detected
|
|||||||
pagination_label: Outlier Detected
|
pagination_label: Outlier Detected
|
||||||
sidebar_label: Outlier Detected
|
sidebar_label: Outlier Detected
|
||||||
sidebar_class_name: outlierDetected
|
sidebar_class_name: outlierDetected
|
||||||
keywords:
|
keywords: ['event', 'trigger', 'outlier', 'detected']
|
||||||
['event', 'trigger', 'outlier', 'detected']
|
|
||||||
description: Fires after an identity was detected as an outlier.
|
description: Fires after an identity was detected as an outlier.
|
||||||
slug: /extensibility/event-triggers/triggers/outlier-detected
|
slug: /extensibility/event-triggers/triggers/outlier-detected
|
||||||
tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
||||||
@@ -13,7 +12,7 @@ tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
|||||||
|
|
||||||
## Event Context
|
## Event Context
|
||||||
|
|
||||||
The 'Outlier Detected' event trigger notifies subscribed applications of any identities that have unusual access when compared to their peers. Outliers are calculated daily, and any identities that are flagged as outliers will be sent to subscribers of the trigger.
|
The 'Outlier Detected' event trigger notifies subscribed applications of any identities that have unusual access when compared to their peers. Outliers are calculated daily, and any identities that are flagged as outliers will be sent to subscribers of the trigger.
|
||||||
|
|
||||||
This is an example input from this trigger:
|
This is an example input from this trigger:
|
||||||
|
|
||||||
@@ -30,7 +29,7 @@ This is an example input from this trigger:
|
|||||||
```
|
```
|
||||||
|
|
||||||
- `outlierType` - Only `LOW_SIMILARITY` is supported at this time.
|
- `outlierType` - Only `LOW_SIMILARITY` is supported at this time.
|
||||||
- `score` - The range is `0.0` to `1.0`. The higher the score, the more likely the identity is an outlier.
|
- `score` - The range is `0.0` to `1.0`. The higher the score, the more likely the identity is an outlier.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ Before consuming this event trigger, the following prerequesites must be met:
|
|||||||
|
|
||||||
:::caution Important
|
:::caution Important
|
||||||
|
|
||||||
If you don't meet the prerequisites and you subscribe to this event trigger, you will not receive any events. The prerequisites must be met in order to receive events.
|
If you don't meet the prerequisites and you subscribe to this event trigger, you will not receive any events. The prerequisites must be met in order to receive events.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ title: Scheduled Search
|
|||||||
pagination_label: Scheduled Search
|
pagination_label: Scheduled Search
|
||||||
sidebar_label: Scheduled Search
|
sidebar_label: Scheduled Search
|
||||||
sidebar_class_name: scheduledSearch
|
sidebar_class_name: scheduledSearch
|
||||||
keywords: ['event', 'trigger', 'saved', 'scheduled', 'search', 'complete', 'available']
|
keywords:
|
||||||
|
['event', 'trigger', 'saved', 'scheduled', 'search', 'complete', 'available']
|
||||||
description: Fires after a scheduled search completes.
|
description: Fires after a scheduled search completes.
|
||||||
slug: /extensibility/event-triggers/triggers/scheduled-search
|
slug: /extensibility/event-triggers/triggers/scheduled-search
|
||||||
tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
tags: ['Event Triggers', 'Available Event Triggers', 'Fire and Forget']
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ After accounts are aggregated and the identity refresh process finds an identity
|
|||||||
|
|
||||||
:::info
|
:::info
|
||||||
|
|
||||||
Identity Security Cloud will **hide** an identity from the identity list in the UI when the authoritative account is removed. This does not necessarily mean that the identity has been deleted. The identity will only be deleted when the above criteria are met. The deletion task run each night, so there will be a delay from when the criteria are met to when the identity will actually be deleted.
|
Identity Security Cloud will **hide** an identity from the identity list in the UI when the authoritative account is removed. This does not necessarily mean that the identity has been deleted. The identity will only be deleted when the above criteria are met. The deletion task run each night, so there will be a delay from when the criteria are met to when the identity will actually be deleted.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ Operators provide more options to filter JSON structures.
|
|||||||
|
|
||||||
### Developing Filters
|
### Developing Filters
|
||||||
|
|
||||||
Developing a filter can be faster when you use a tool like an online [JSONpath editor](https://www.javainuse.com/jsonpath). These tools can provide quick feedback on your filter, allowing you to focus on the exact filter expression you want before testing it on a trigger. Just paste an example of your event trigger input and start crafting an expression to see its result.
|
Developing a filter can be faster when you use a tool like an online [JSONpath editor](https://www.javainuse.com/jsonpath). These tools can provide quick feedback on your filter, allowing you to focus on the exact filter expression you want before testing it on a trigger. Just paste an example of your event trigger input and start crafting an expression to see its result.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ sidebar_label: Trigger Types
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: triggerTypes
|
sidebar_class_name: triggerTypes
|
||||||
keywords: ['event', 'trigger', 'types']
|
keywords: ['event', 'trigger', 'types']
|
||||||
description: These are the different trigger types you can use.
|
description: These are the different trigger types you can use.
|
||||||
slug: /extensibility/event-triggers/trigger-types
|
slug: /extensibility/event-triggers/trigger-types
|
||||||
tags: ['Event Triggers']
|
tags: ['Event Triggers']
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"customProps": {
|
"customProps": {
|
||||||
"description": "Advanced configurations with custom logic."
|
"description": "Advanced configurations with custom logic."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,24 +19,24 @@ This rule generates complex account attribute values during provisioning, e.g. w
|
|||||||
In the following example, the template is `${firstname}.${lastname}${uniqueCounter}`, which is pulled in by the `Create Unique LDAP Attribute` rule and used to replace the `firstname`, `lastname` and `uniqueCounter` placeholders.
|
In the following example, the template is `${firstname}.${lastname}${uniqueCounter}`, which is pulled in by the `Create Unique LDAP Attribute` rule and used to replace the `firstname`, `lastname` and `uniqueCounter` placeholders.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"name": "userName",
|
"name": "userName",
|
||||||
"transform": {
|
"transform": {
|
||||||
"type": "rule",
|
"type": "rule",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"name": "Create Unique LDAP Attribute"
|
"name": "Create Unique LDAP Attribute"
|
||||||
}
|
|
||||||
},
|
|
||||||
"attributes": {
|
|
||||||
"template": "${firstname}.${lastname}${uniqueCounter}",
|
|
||||||
"cloudMaxUniqueChecks": "50",
|
|
||||||
"cloudMaxSize": "20",
|
|
||||||
"cloudRequired": "true"
|
|
||||||
},
|
|
||||||
"isRequired": false,
|
|
||||||
"type": "string",
|
|
||||||
"isMultiValued": false
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"attributes": {
|
||||||
|
"template": "${firstname}.${lastname}${uniqueCounter}",
|
||||||
|
"cloudMaxUniqueChecks": "50",
|
||||||
|
"cloudMaxSize": "20",
|
||||||
|
"cloudRequired": "true"
|
||||||
|
},
|
||||||
|
"isRequired": false,
|
||||||
|
"type": "string",
|
||||||
|
"isMultiValued": false
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Execution
|
## Execution
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ Use this rule to modify a provisioning plan as provisioning is sent out. Do not
|
|||||||
|
|
||||||
These are some examples of when to use this rule:
|
These are some examples of when to use this rule:
|
||||||
|
|
||||||
* Disable account and remove groups during provisioning when the lifecycle state of an identity is set to terminated
|
- Disable account and remove groups during provisioning when the lifecycle state of an identity is set to terminated
|
||||||
* Remove or add permissions when certain attribute criteria are met
|
- Remove or add permissions when certain attribute criteria are met
|
||||||
* Move users to a specific organizational unit (OU) in Active Directory based upon attribute criteria
|
- Move users to a specific organizational unit (OU) in Active Directory based upon attribute criteria
|
||||||
|
|
||||||
## Execution
|
## Execution
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ tags: ['Rules']
|
|||||||
|
|
||||||
This rule manipulates raw input data provided by the rows and columns in a file and builds a map from the incoming data. Use this rule to create a new value by combining two columns together. For example, if one column was `access` and another `permissions` you could combine these together to create an entitlement `admin-read`.
|
This rule manipulates raw input data provided by the rows and columns in a file and builds a map from the incoming data. Use this rule to create a new value by combining two columns together. For example, if one column was `access` and another `permissions` you could combine these together to create an entitlement `admin-read`.
|
||||||
|
|
||||||
:::info
|
:::info This rule runs in the cloud, but it's really a connector rule because it executes against the DelimitedFileConnector. :::
|
||||||
This rule runs in the cloud, but it's really a connector rule because it executes against the DelimitedFileConnector.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Execution
|
## Execution
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ All submitted rules must follow proper rule submission guidelines.
|
|||||||
|
|
||||||
This is the file naming convention for rules: `Rule - {type} - {name}.xml`
|
This is the file naming convention for rules: `Rule - {type} - {name}.xml`
|
||||||
|
|
||||||
For example, this is the rule:
|
For example, this is the rule:
|
||||||
|
|
||||||
`<Rule language="beanshell" name="Calculate Lifecycle" type="IdentityAttribute">`
|
`<Rule language="beanshell" name="Calculate Lifecycle" type="IdentityAttribute">`
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ This rule calculates a manager relationship between identities.
|
|||||||
|
|
||||||
Use this rule to correlate an identity's manager for the following scenarios:
|
Use this rule to correlate an identity's manager for the following scenarios:
|
||||||
|
|
||||||
* The authoritative source has multiple accounts for an identity and you must pick the manager data from the `active` account.
|
- The authoritative source has multiple accounts for an identity and you must pick the manager data from the `active` account.
|
||||||
* You need to do a lookup from an employee number to other data.
|
- You need to do a lookup from an employee number to other data.
|
||||||
* The identity changes types, for example, from consultant to employee with the manager coming from a different authoritative source.
|
- The identity changes types, for example, from consultant to employee with the manager coming from a different authoritative source.
|
||||||
|
|
||||||
The manager correlation rule runs before configured manager account correlation.
|
The manager correlation rule runs before configured manager account correlation.
|
||||||
|
|
||||||
|
|||||||
@@ -131,16 +131,12 @@ The value key is a list. All available AfterCreate, AfterModify, BeforeCreate, a
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"op": "add",
|
"op": "add",
|
||||||
"path": "/connectorAttributes/nativeRules",
|
"path": "/connectorAttributes/nativeRules",
|
||||||
"value": [
|
"value": ["Example Rule 1", "Example Rule 2"]
|
||||||
"Example Rule 1",
|
}
|
||||||
"Example Rule 2"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Correlation Rule
|
### Correlation Rule
|
||||||
|
|||||||
@@ -216,8 +216,8 @@ if(fullName.length() > MAX_USERNAME_LENGTH) {
|
|||||||
|
|
||||||
int firstNameLength = firstName.length();
|
int firstNameLength = firstName.length();
|
||||||
|
|
||||||
//Checking if the firstname length is more than the MAX minus 2 chars.
|
//Checking if the firstname length is more than the MAX minus 2 chars.
|
||||||
//If firstname is more then the MAX minus 2 we are picking MAX minus 2 characters from the firstname.
|
//If firstname is more then the MAX minus 2 we are picking MAX minus 2 characters from the firstname.
|
||||||
if(firstNameLength > (MAX_USERNAME_LENGTH - 2)){
|
if(firstNameLength > (MAX_USERNAME_LENGTH - 2)){
|
||||||
//lastNameLength represents the current pointer of lastlength.
|
//lastNameLength represents the current pointer of lastlength.
|
||||||
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
||||||
@@ -229,7 +229,7 @@ if(fullName.length() > MAX_USERNAME_LENGTH) {
|
|||||||
finalUserName = username;
|
finalUserName = username;
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//If firstname is less than or equal to the MAX minus 2 chars then we are considering full firstname for username generation.
|
//If firstname is less than or equal to the MAX minus 2 chars then we are considering full firstname for username generation.
|
||||||
else{
|
else{
|
||||||
@@ -243,8 +243,8 @@ if(fullName.length() > MAX_USERNAME_LENGTH) {
|
|||||||
finalUserName = username;
|
finalUserName = username;
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ if( isUnique( username ) ) {
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//If the username was not unique with firstname.last name we then check uniqueness
|
//If the username was not unique with firstname.last name we then check uniqueness
|
||||||
// with firstname.firstLetterOfLastName, firstname.secondLetterOfLastName e.t.c...
|
// with firstname.firstLetterOfLastName, firstname.secondLetterOfLastName e.t.c...
|
||||||
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
||||||
username = firstName + "." + lastName.charAt(lastNameLength);
|
username = firstName + "." + lastName.charAt(lastNameLength);
|
||||||
@@ -290,8 +290,7 @@ public boolean isUnique ( String username ) throws GeneralException {
|
|||||||
|
|
||||||
### Invoke `generateUsername()` With the Identity's First and Last Name
|
### Invoke `generateUsername()` With the Identity's First and Last Name
|
||||||
|
|
||||||
This is the final part of the rule. Call the `generateUsername()` function, passing in the identity's first and last name.
|
This is the final part of the rule. Call the `generateUsername()` function, passing in the identity's first and last name. The `identity` variable is already initialized and included as input to our attribute generator rule.
|
||||||
The `identity` variable is already initialized and included as input to our attribute generator rule.
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
return generateUsername( identity.getFirstname(), identity.getLastname() );
|
return generateUsername( identity.getFirstname(), identity.getLastname() );
|
||||||
@@ -354,8 +353,8 @@ return generateUsername( identity.getFirstname(), identity.getLastname() );
|
|||||||
|
|
||||||
int firstNameLength = firstName.length();
|
int firstNameLength = firstName.length();
|
||||||
|
|
||||||
//Checking if the firstname length is more than the MAX minus 2 chars.
|
//Checking if the firstname length is more than the MAX minus 2 chars.
|
||||||
//If firstname is more then the MAX minus 2 we are picking MAX minus 2 characters from the firstname.
|
//If firstname is more then the MAX minus 2 we are picking MAX minus 2 characters from the firstname.
|
||||||
if(firstNameLength > (MAX_USERNAME_LENGTH - 2)){
|
if(firstNameLength > (MAX_USERNAME_LENGTH - 2)){
|
||||||
//lastNameLength represents the current pointer of lastlength.
|
//lastNameLength represents the current pointer of lastlength.
|
||||||
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
||||||
@@ -367,7 +366,7 @@ return generateUsername( identity.getFirstname(), identity.getLastname() );
|
|||||||
finalUserName = username;
|
finalUserName = username;
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//If firstname is less than or equal to the MAX minus 2 chars then we are considering full firstname for username generation.
|
//If firstname is less than or equal to the MAX minus 2 chars then we are considering full firstname for username generation.
|
||||||
else{
|
else{
|
||||||
@@ -381,8 +380,8 @@ return generateUsername( identity.getFirstname(), identity.getLastname() );
|
|||||||
finalUserName = username;
|
finalUserName = username;
|
||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//The full name is less than MAX_USERNAME_LENGTH minus 2 chars directly assign username to full name.
|
//The full name is less than MAX_USERNAME_LENGTH minus 2 chars directly assign username to full name.
|
||||||
username = fullName;
|
username = fullName;
|
||||||
@@ -394,7 +393,7 @@ return generateUsername( identity.getFirstname(), identity.getLastname() );
|
|||||||
return username;
|
return username;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//If the username was not unique with firstname.last name we then check uniqueness
|
//If the username was not unique with firstname.last name we then check uniqueness
|
||||||
// with firstname.firstLetterOfLastName, firstname.secondLetterOfLastName e.t.c...
|
// with firstname.firstLetterOfLastName, firstname.secondLetterOfLastName e.t.c...
|
||||||
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
for(int lastNameLength = 0 ; lastNameLength < lastName.length() ; lastNameLength++){
|
||||||
username = firstName + "." + lastName.charAt(lastNameLength);
|
username = firstName + "." + lastName.charAt(lastNameLength);
|
||||||
@@ -418,7 +417,7 @@ return generateUsername( identity.getFirstname(), identity.getLastname() );
|
|||||||
public boolean isUnique ( String username ) throws GeneralException {
|
public boolean isUnique ( String username ) throws GeneralException {
|
||||||
return !idn.accountExistsByDisplayName(application.getName(), username);
|
return !idn.accountExistsByDisplayName(application.getName(), username);
|
||||||
}
|
}
|
||||||
|
|
||||||
return generateUsername( identity.getFirstname(), identity.getLastname() );
|
return generateUsername( identity.getFirstname(), identity.getLastname() );
|
||||||
]]></Source>
|
]]></Source>
|
||||||
</Rule>
|
</Rule>
|
||||||
@@ -458,14 +457,14 @@ No errors found.
|
|||||||
|
|
||||||
Warnings: (3)
|
Warnings: (3)
|
||||||
|
|
||||||
Line 55 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
Line 55 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
||||||
55: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
55: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
||||||
|
|
||||||
Line 70 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
Line 70 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
||||||
70: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
70: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
||||||
|
|
||||||
Line 95 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
Line 95 - [LintValidatorForStatement(31)] For statement detected: for ( int lastNameLength = 0 ; . . "For Loops" can cause issues when looping with incorrect exit conditions. Ensure Looping exit conditions are correct.
|
||||||
95: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
95: for ( int lastNameLength = 0 ; lastNameLength < lastName .length ( ) ; lastNameLength ++ ) {
|
||||||
|
|
||||||
|
|
||||||
________________________________________________________________________________
|
________________________________________________________________________________
|
||||||
|
|||||||
@@ -502,19 +502,19 @@ String value, String sortAttribute)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this method to call LDAP type connectors to look for
|
* Use this method to call LDAP type connectors to look for
|
||||||
* unique values. This method calls the connector with a specific search filter
|
* unique values. This method calls the connector with a specific search filter
|
||||||
* based on the attributeName and value passed into the method.
|
* based on the attributeName and value passed into the method.
|
||||||
* Any returned value is considered non-unique.
|
* Any returned value is considered non-unique.
|
||||||
*
|
*
|
||||||
* @param identityNameOrId The name or ID of the identity you are using
|
* @param identityNameOrId The name or ID of the identity you are using
|
||||||
* @param applicationNameOrId The name or ID of the source you are targeting
|
* @param applicationNameOrId The name or ID of the source you are targeting
|
||||||
* @param attributeName The name of the attribute you want to validate
|
* @param attributeName The name of the attribute you want to validate
|
||||||
* @param attributeValue The value of the attribute you want to validate
|
* @param attributeValue The value of the attribute you want to validate
|
||||||
*
|
*
|
||||||
* @return true if the value is unique AND false otherwise. If the application or identity can't be found, an
|
* @return true if the value is unique AND false otherwise. If the application or identity can't be found, an
|
||||||
* IllegalStateException will be thrown.
|
* IllegalStateException will be thrown.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public boolean isUniqueLDAPValue(String identityNameOrId, String applicationNameOrId, String attributeName, String attributeValue)
|
public boolean isUniqueLDAPValue(String identityNameOrId, String applicationNameOrId, String attributeName, String attributeValue)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"customProps": {
|
"customProps": {
|
||||||
"description": "Modify attribute data without code."
|
"description": "Modify attribute data without code."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ tags: ['Transforms', 'Guides', 'identity']
|
|||||||
|
|
||||||
Transforms ship with the Apache Velocity template engine, which allows a transform to reference, transform, and render values passed into the transform context.
|
Transforms ship with the Apache Velocity template engine, which allows a transform to reference, transform, and render values passed into the transform context.
|
||||||
|
|
||||||
The following variables are available to the Apache Velocity template engine when a transform is used to source an identity attribute:
|
The following variables are available to the Apache Velocity template engine when a transform is used to source an identity attribute:
|
||||||
|
|
||||||
| Variable | Type | Description |
|
| Variable | Type | Description |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
@@ -25,7 +25,7 @@ The following variables are available to the Apache Velocity template engine whe
|
|||||||
|
|
||||||
For available methods on these objects see our [Rules Java Docs](https://developer.sailpoint.com/docs/extensibility/rules/java-docs).
|
For available methods on these objects see our [Rules Java Docs](https://developer.sailpoint.com/docs/extensibility/rules/java-docs).
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
These examples will help you learn what you can do with the identity context.
|
These examples will help you learn what you can do with the identity context.
|
||||||
|
|
||||||
@@ -56,14 +56,17 @@ You must use a `firstValid`. If the identity does not have a manager, `getManage
|
|||||||
{
|
{
|
||||||
"type": "firstValid",
|
"type": "firstValid",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"values": ["$identity.getManager().getStringAttribute('country')", "no manager exists"]
|
"values": [
|
||||||
|
"$identity.getManager().getStringAttribute('country')",
|
||||||
|
"no manager exists"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Get manager status of the identity's manager
|
### Get manager status of the identity's manager
|
||||||
|
|
||||||
This example would get the status of whether or not the identity's manager is currently actually a manager.
|
This example would get the status of whether or not the identity's manager is currently actually a manager.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -76,7 +79,7 @@ This example would get the status of whether or not the identity's manager is cu
|
|||||||
|
|
||||||
### Get an identity's accounts
|
### Get an identity's accounts
|
||||||
|
|
||||||
This example would get an identity's various associated source accounts.
|
This example would get an identity's various associated source accounts.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -89,7 +92,7 @@ This example would get an identity's various associated source accounts.
|
|||||||
|
|
||||||
### Get a comma separated list of account names from an application/source
|
### Get a comma separated list of account names from an application/source
|
||||||
|
|
||||||
This is the velocity logic of the transform:
|
This is the velocity logic of the transform:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
/* Loop through accounts returned from get accounts by application id */
|
/* Loop through accounts returned from get accounts by application id */
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ tags: ['Transforms', 'Guides', 'Lifecycle']
|
|||||||
|
|
||||||
In this guide, you will walk through a lifecycle state transform that requires you to nest multiple transforms together to achieve your desired result.
|
In this guide, you will walk through a lifecycle state transform that requires you to nest multiple transforms together to achieve your desired result.
|
||||||
|
|
||||||
A lifecycle state is a status an identity can be in, such as `active`, `inactive` and `terminated`, for example. You can then use this lifecycle state in Identity Security Cloud to determine an identity's access.
|
A lifecycle state is a status an identity can be in, such as `active`, `inactive` and `terminated`, for example. You can then use this lifecycle state in Identity Security Cloud to determine an identity's access.
|
||||||
|
|
||||||
## Determine lifecycle state from end date attribute
|
## Determine lifecycle state from end date attribute
|
||||||
|
|
||||||
@@ -38,24 +38,24 @@ This example and dates assume that the `now` keyword in the dateMath expression
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
| id | email | first_name | last_name | end_date |
|
| id | email | first_name | last_name | end_date |
|
||||||
| ------ | ---------------------------- | ---------- | --------- | ---------- |
|
| --- | --- | --- | --- | --- |
|
||||||
| 100010 | lewis.hamilton@sailpoint.com | Lewis | Hamilton | 2023-11-01 |
|
| 100010 | lewis.hamilton@sailpoint.com | Lewis | Hamilton | 2023-11-01 |
|
||||||
| 100011 | frank.williams@sailpoint.com | Frank | Williams | 2023-11-09 |
|
| 100011 | frank.williams@sailpoint.com | Frank | Williams | 2023-11-09 |
|
||||||
| 100012 | paddy.lowe@sailpoint.com | Paddy | Lowe | 2023-11-25 |
|
| 100012 | paddy.lowe@sailpoint.com | Paddy | Lowe | 2023-11-25 |
|
||||||
| 100013 | keifer.sutherland@sailpoint.com | Keifer | Sutherland | 2023-12-25 |
|
| 100013 | keifer.sutherland@sailpoint.com | Keifer | Sutherland | 2023-12-25 |
|
||||||
|
|
||||||
### Check whether the end date was in the past
|
### Check whether the end date was in the past
|
||||||
|
|
||||||
The first part of the transform will check whether the `end_date` attribute was in the past. You will use these transforms to do so: `dateCompare`, `dateFormat`, and `dateMath`.
|
The first part of the transform will check whether the `end_date` attribute was in the past. You will use these transforms to do so: `dateCompare`, `dateFormat`, and `dateMath`.
|
||||||
|
|
||||||
First, use the [dateCompare operation](../operations/date-compare.md) to check that today is less than the specified `end_date`. To use the `dateCompare` operation, the dates must be in the `ISO8601` format, so the transform will require the use of the [dateFormat operation](../operations/date-format.md) as well.
|
First, use the [dateCompare operation](../operations/date-compare.md) to check that today is less than the specified `end_date`. To use the `dateCompare` operation, the dates must be in the `ISO8601` format, so the transform will require the use of the [dateFormat operation](../operations/date-format.md) as well.
|
||||||
|
|
||||||
On lines 10-17, the [dathMath operation](../operations/date-math.md) to pull the date `now`, which represents the current moment in time. The `dateFormat` operation then converts it into the `ISO8601` format for comparison.
|
On lines 10-17, the [dathMath operation](../operations/date-math.md) to pull the date `now`, which represents the current moment in time. The `dateFormat` operation then converts it into the `ISO8601` format for comparison.
|
||||||
|
|
||||||
On lines 21-31, the `dateFormat` operation converts the end date provided from the source format (`YYYY-MM-dd`) into the `ISO8601` format.
|
On lines 21-31, the `dateFormat` operation converts the end date provided from the source format (`YYYY-MM-dd`) into the `ISO8601` format.
|
||||||
|
|
||||||
Finally, lines 34-36 use the comparison operator greater than or equal to `gte`. If the current date is greater than or equal to the end date, the comparison will return `true`, meaning that the end date is in the past. This would result in identity's `terminated` lifecycle state. If the current date is still less than the end date, the comparison will return `false`.
|
Finally, lines 34-36 use the comparison operator greater than or equal to `gte`. If the current date is greater than or equal to the end date, the comparison will return `true`, meaning that the end date is in the past. This would result in identity's `terminated` lifecycle state. If the current date is still less than the end date, the comparison will return `false`.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Show Transform</summary>
|
<summary>Show Transform</summary>
|
||||||
@@ -108,11 +108,11 @@ Finally, lines 34-36 use the comparison operator greater than or equal to `gte`.
|
|||||||
|
|
||||||
### Check whether end date is within 7 days
|
### Check whether end date is within 7 days
|
||||||
|
|
||||||
Once you have ensured that the `end_date` is in fact in the past, the next step is to check whether the `end_date` is fewer than 7 days away, 7-25 days days away, or more than 25 days away, to determine their exact lifecycle states. Start by checking whether the `end_date` is fewer than 7 days away. You will again use `dateCompare`, `dateFormat`, and `dateMath` for this comparison.
|
Once you have ensured that the `end_date` is in fact in the past, the next step is to check whether the `end_date` is fewer than 7 days away, 7-25 days days away, or more than 25 days away, to determine their exact lifecycle states. Start by checking whether the `end_date` is fewer than 7 days away. You will again use `dateCompare`, `dateFormat`, and `dateMath` for this comparison.
|
||||||
|
|
||||||
On line 27, use the `dateMath` operation to add 7 days to the current date: `now+7d`. It pulls in the `end_date` the same way it did before, and it converts both dates to the `ISO8601` format for comparison.
|
On line 27, use the `dateMath` operation to add 7 days to the current date: `now+7d`. It pulls in the `end_date` the same way it did before, and it converts both dates to the `ISO8601` format for comparison.
|
||||||
|
|
||||||
Lines 34-36 use the comparison operator less than or equal to: `lte`. This uses the result from the previous check to ensure that if the `end_date` is not in the past and that it is also fewer than 7 days away, the `end_date` will indeed occur in the 0-7 days range. This would result in the identity's `inactivePendingTermination` lifecycle state.
|
Lines 34-36 use the comparison operator less than or equal to: `lte`. This uses the result from the previous check to ensure that if the `end_date` is not in the past and that it is also fewer than 7 days away, the `end_date` will indeed occur in the 0-7 days range. This would result in the identity's `inactivePendingTermination` lifecycle state.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Show Transform</summary>
|
<summary>Show Transform</summary>
|
||||||
@@ -169,7 +169,7 @@ Once you have ensured that the end date is in the past and that it is not fewer
|
|||||||
|
|
||||||
On line 27, the `dateMath` operation adds 25 days to the current date `now+25d`. It pulls in the end date the same way it did before, and it converts both dates to the `ISO8601` format for comparison.
|
On line 27, the `dateMath` operation adds 25 days to the current date `now+25d`. It pulls in the end date the same way it did before, and it converts both dates to the `ISO8601` format for comparison.
|
||||||
|
|
||||||
Lines 34-36 use the comparison operator less than or equal to: `lte`. This uses the combination of the previous checks to ensure that if the `end_date` is not in the past, it is greater than 7 days away, and it returns `true` that it is fewer than 25 days away, then the `end_date` must fall between 7 and 25 days away. This would result in the identity's `activePendingTermination` lifecycle state. If it returns `false`, then the `end_date` must be more than 25 days away. This would result in the identity's `active` lifecycle state.
|
Lines 34-36 use the comparison operator less than or equal to: `lte`. This uses the combination of the previous checks to ensure that if the `end_date` is not in the past, it is greater than 7 days away, and it returns `true` that it is fewer than 25 days away, then the `end_date` must fall between 7 and 25 days away. This would result in the identity's `activePendingTermination` lifecycle state. If it returns `false`, then the `end_date` must be more than 25 days away. This would result in the identity's `active` lifecycle state.
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Show Transform</summary>
|
<summary>Show Transform</summary>
|
||||||
@@ -236,7 +236,7 @@ Now that you have taken the time to understand each of the nested transforms, yo
|
|||||||
#end
|
#end
|
||||||
```
|
```
|
||||||
|
|
||||||
This is the logic within the static transform:
|
This is the logic within the static transform:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -371,9 +371,9 @@ This is the logic within the static transform:
|
|||||||
|
|
||||||
These are the results of the transform on each identity, given that `now` returns 2023-11-07:
|
These are the results of the transform on each identity, given that `now` returns 2023-11-07:
|
||||||
|
|
||||||
| id | email | first_name | last_name | end_date | result |
|
| id | email | first_name | last_name | end_date | result |
|
||||||
| ------ | ---------------------------- | ---------- | --------- | ---------- | ------ |
|
| --- | --- | --- | --- | --- | --- |
|
||||||
| 100010 | lewis.hamilton@sailpoint.com | Lewis | Hamilton | 2023-11-01 | terminated |
|
| 100010 | lewis.hamilton@sailpoint.com | Lewis | Hamilton | 2023-11-01 | terminated |
|
||||||
| 100011 | frank.williams@sailpoint.com | Frank | Williams | 2023-11-09 | inactivePendingTermination |
|
| 100011 | frank.williams@sailpoint.com | Frank | Williams | 2023-11-09 | inactivePendingTermination |
|
||||||
| 100012 | paddy.lowe@sailpoint.com | Paddy | Lowe | 2023-11-25 | activePendingTermination |
|
| 100012 | paddy.lowe@sailpoint.com | Paddy | Lowe | 2023-11-25 | activePendingTermination |
|
||||||
| 100013 | keifer.sutherland@sailpoint.com | Keifer | Sutherland | 2023-12-25 | active |
|
| 100013 | keifer.sutherland@sailpoint.com | Keifer | Sutherland | 2023-12-25 | active |
|
||||||
|
|||||||
@@ -129,13 +129,11 @@ This is an example create provisioning policy response for a source:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Add to the Create policy
|
## Add to the Create policy
|
||||||
|
|
||||||
This transform concatenates the identityAttributes `firstName`, `lastName`, the two digit month of the `hireDate` and the static string `Rt4e!` to form a temporaryPassword.
|
This transform concatenates the identityAttributes `firstName`, `lastName`, the two digit month of the `hireDate` and the static string `Rt4e!` to form a temporaryPassword.
|
||||||
|
|
||||||
:::caution
|
:::caution You must use the `identityAttribute` type when you're writing transforms in provisioning policies. The `accountAttribute` type won't work during provisioning. :::
|
||||||
You must use the `identityAttribute` type when you're writing transforms in provisioning policies. The `accountAttribute` type won't work during provisioning.
|
|
||||||
:::
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -197,7 +195,7 @@ If you assume the given attributes have the following values, this transform wou
|
|||||||
|
|
||||||
Upload your complete CREATE provisioning policy by using the [Create Provisioning Policy API](/docs/api/v3/create-provisioning-policy), or use the [Update Provisioning Policy API](/docs/api/v3/put-provisioning-policy) to update an existing provisioning policy.
|
Upload your complete CREATE provisioning policy by using the [Create Provisioning Policy API](/docs/api/v3/create-provisioning-policy), or use the [Update Provisioning Policy API](/docs/api/v3/put-provisioning-policy) to update an existing provisioning policy.
|
||||||
|
|
||||||
This is the example response with the full policy, along with the new attribute:
|
This is the example response with the full policy, along with the new attribute:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ Account attribute transforms are configured on the account create profiles. They
|
|||||||
These transforms are configured separately from the transforms applied via the identity profile mappings tab.
|
These transforms are configured separately from the transforms applied via the identity profile mappings tab.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
#### Configuration
|
#### Configuration
|
||||||
|
|
||||||
These can be configured in Identity Security Cloud by going to **Admin** > **Sources** > (A Source) > **Accounts** (tab) > **Create Account**.
|
These can be configured in Identity Security Cloud by going to **Admin** > **Sources** > (A Source) > **Accounts** (tab) > **Create Account**.
|
||||||
|
|||||||
@@ -147,36 +147,36 @@ When you are mapping values like a username, focus on primary accounts from a pa
|
|||||||
To determine whether an identity is a member of an entitlement.
|
To determine whether an identity is a member of an entitlement.
|
||||||
|
|
||||||
- `input` contains the condition to be evaluated (is member of an entitlement or not). If the user doesn't meet the below conditions, the `firstValid` retuns "FALSE".
|
- `input` contains the condition to be evaluated (is member of an entitlement or not). If the user doesn't meet the below conditions, the `firstValid` retuns "FALSE".
|
||||||
- `sourceName` is "Active Directory" because that is the source this data is coming from.
|
- `sourceName` is "Active Directory" because that is the source this data is coming from.
|
||||||
- `attributeName` is "sAMAccountName" because you are mapping the username of the user.
|
- `attributeName` is "sAMAccountName" because you are mapping the username of the user.
|
||||||
- `accountPropertyFilter` is filtering accounts that are members of an entitlement that contains "All AD Users-rshwart".
|
- `accountPropertyFilter` is filtering accounts that are members of an entitlement that contains "All AD Users-rshwart".
|
||||||
- `table` contains the boolean results: FALSE or TRUE (default).
|
- `table` contains the boolean results: FALSE or TRUE (default).
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"input": {
|
"input": {
|
||||||
|
"attributes": {
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"values": [
|
"accountPropertyFilter": "(memberOf.contains(\"All AD Users-rshwart\"))",
|
||||||
{
|
"attributeName": "sAMAccountName",
|
||||||
"attributes": {
|
"sourceName": "Active Directory"
|
||||||
"accountPropertyFilter": "(memberOf.contains(\"All AD Users-rshwart\"))",
|
|
||||||
"attributeName": "sAMAccountName",
|
|
||||||
"sourceName": "Active Directory"
|
|
||||||
},
|
|
||||||
"type": "accountAttribute"
|
|
||||||
},
|
|
||||||
"FALSE"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"type": "firstValid"
|
"type": "accountAttribute"
|
||||||
},
|
},
|
||||||
"table": {
|
"FALSE"
|
||||||
"FALSE": "FALSE",
|
]
|
||||||
"default": "TRUE"
|
},
|
||||||
}
|
"type": "firstValid"
|
||||||
},
|
},
|
||||||
"id": "Contains IT Access",
|
"table": {
|
||||||
"type": "lookup"
|
"FALSE": "FALSE",
|
||||||
|
"default": "TRUE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "Contains IT Access",
|
||||||
|
"type": "lookup"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ This transform leverages the Java SimpleDateFormat syntax; see the [References](
|
|||||||
|
|
||||||
## Transform Structure
|
## Transform Structure
|
||||||
|
|
||||||
The date format transform takes whatever value provided as the input, parses the datetime based on the `inputFormat` provided, and then reformats it into the desired `outputFormat`.
|
The date format transform takes whatever value provided as the input, parses the datetime based on the `inputFormat` provided, and then reformats it into the desired `outputFormat`.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -53,11 +53,9 @@ The date format transform takes whatever value provided as the input, parses the
|
|||||||
- If no inputFormat is provided, the transform assumes that it is in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601).
|
- If no inputFormat is provided, the transform assumes that it is in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601).
|
||||||
- **outputFormat** - This string value indicates either the explicit SimpleDateFormat or the built-in named format that the data is formatted into.
|
- **outputFormat** - This string value indicates either the explicit SimpleDateFormat or the built-in named format that the data is formatted into.
|
||||||
- If no outputFormat is provided, the transform assumes that it is in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601).
|
- If no outputFormat is provided, the transform assumes that it is in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601).
|
||||||
- **input** - This is an optional attribute that can explicitly define the input data passed into the transform logic. If no input is provided, the transform takes its input from the source and attribute combination configured with the UI.
|
- **input** - This is an optional attribute that can explicitly define the input data passed into the transform logic. If no input is provided, the transform takes its input from the source and attribute combination configured with the UI.
|
||||||
|
|
||||||
:::note Important
|
:::note Important This transform does not currently support the "now" keyword as an input value. :::
|
||||||
This transform does not currently support the "now" keyword as an input value.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ Use the date math transform to add, subtract, and round components of a timestam
|
|||||||
|
|
||||||
The output format for the DateMath transform is "yyyy-MM-dd'T'HH:mm". When you use this transform inside another transform (e.g., [dateCompare](./date-compare.md)), make sure to convert to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) first.
|
The output format for the DateMath transform is "yyyy-MM-dd'T'HH:mm". When you use this transform inside another transform (e.g., [dateCompare](./date-compare.md)), make sure to convert to [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) first.
|
||||||
|
|
||||||
|
|
||||||
:::note Other Considerations
|
:::note Other Considerations
|
||||||
|
|
||||||
- The input datetime value must always be in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601), in UTC time zone:
|
- The input datetime value must always be in [ISO8601 format](https://en.wikipedia.org/wiki/ISO_8601), in UTC time zone:
|
||||||
@@ -90,6 +89,7 @@ Some examples of expressions are:
|
|||||||
|
|
||||||
- `true` indicates the transform rounds up (i.e., truncate the fractional date/time component indicated and then add one unit of that component).
|
- `true` indicates the transform rounds up (i.e., truncate the fractional date/time component indicated and then add one unit of that component).
|
||||||
- `false` indicates the transform rounds down (i.e., truncate the fractional date/time component indicated).
|
- `false` indicates the transform rounds down (i.e., truncate the fractional date/time component indicated).
|
||||||
|
|
||||||
- **input** - This is an optional attribute that can explicitly define the input data passed into the transform logic. If no input is provided, the transform takes its input from the source and attribute combination configured with the UI.
|
- **input** - This is an optional attribute that can explicitly define the input data passed into the transform logic. If no input is provided, the transform takes its input from the source and attribute combination configured with the UI.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ The following are examples of diacritical marks:
|
|||||||
> - Ň
|
> - Ň
|
||||||
> - Ŵ
|
> - Ŵ
|
||||||
|
|
||||||
The decomposeDiacriticalMarks transform uses the [Normalizer library](https://docs.oracle.com/javase/7/docs/api/java/text/Normalizer.html) to decompose the diacritical marks. It specifically uses the Normalization Form KD (NFKD), as described in Sections 3.6, 3.10, and 3.11 of the Unicode Standard, also summarized under [Annex 4: Decomposition](https://www.unicode.org/reports/tr15/tr15-23.html#Decomposition).
|
The decomposeDiacriticalMarks transform uses the [Normalizer library](https://docs.oracle.com/javase/7/docs/api/java/text/Normalizer.html) to decompose the diacritical marks. It specifically uses the Normalization Form KD (NFKD), as described in Sections 3.6, 3.10, and 3.11 of the Unicode Standard, also summarized under [Annex 4: Decomposition](https://www.unicode.org/reports/tr15/tr15-23.html#Decomposition).
|
||||||
|
|
||||||
After decomposition, the transform uses a [Regex Replace](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html) to replace all diacritical marks by using the `InCombiningDiacriticalMarks` property of Unicode (ex. `replaceAll("[\\p{InCombiningDiacriticalMarks}]", "")`).
|
After decomposition, the transform uses a [Regex Replace](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html) to replace all diacritical marks by using the `InCombiningDiacriticalMarks` property of Unicode (ex. `replaceAll("[\\p{InCombiningDiacriticalMarks}]", "")`).
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ Output: "Dubcek"
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
To run some tests in code, use this java code to compare the results of what the transform does to what your code does:
|
To run some tests in code, use this java code to compare the results of what the transform does to what your code does:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
import java.text.Normalizer;
|
import java.text.Normalizer;
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ sidebar_label: Guides
|
|||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
sidebar_class_name: guides
|
sidebar_class_name: guides
|
||||||
keywords: ['guides']
|
keywords: ['guides']
|
||||||
description: ISC guides.
|
description: ISC guides.
|
||||||
slug: /guides
|
slug: /guides
|
||||||
tags: ['guides']
|
tags: ['guides']
|
||||||
---
|
---
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
Identity Security Cloud (ISC) has all sorts of potential specific solutions you can implement as long as you know how. These specific solutions may either not fall into one of the extensibility, connectivity, tools, or reporting categories, or they may fall into multiple categories. Read these guides to learn how to implement these specific solutions.
|
|
||||||
|
Identity Security Cloud (ISC) has all sorts of potential specific solutions you can implement as long as you know how. These specific solutions may either not fall into one of the extensibility, connectivity, tools, or reporting categories, or they may fall into multiple categories. Read these guides to learn how to implement these specific solutions.
|
||||||
|
|
||||||
```mdx-code-block
|
```mdx-code-block
|
||||||
import DocCardList from '@theme/DocCardList';
|
import DocCardList from '@theme/DocCardList';
|
||||||
@@ -21,7 +22,8 @@ import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
|||||||
<DocCardList items={useCurrentSidebarCategory().items}/>
|
<DocCardList items={useCurrentSidebarCategory().items}/>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discuss
|
## Discuss
|
||||||
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
|
||||||
|
|
||||||
To learn more about these ISC topics and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
The most valuable resource for ISC developers is the SailPoint Developer Community itself, where ISC users and experts all over the world come together to ask questions and provide solutions.
|
||||||
|
|
||||||
|
To learn more about these ISC topics and discuss them with SailPoint Developer Community members, go to the [SailPoint Developer Community Forum](https://developer.sailpoint.com/discuss/c/isc/6).
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user