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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions product/admin/functions-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ curl -X POST "$C1_TENANT/api/v1/functions" \
-d '{
"displayName": "My Function",
"description": "Checks user access",
"functionType": "FUNCTION_TYPE_DEFAULT"
"functionType": "FUNCTION_TYPE_ANY"
}'
```

Expand All @@ -47,7 +47,7 @@ curl -X POST "$C1_TENANT/api/v1/functions" \
-d '{
"displayName": "My Function",
"description": "Checks user access",
"functionType": "FUNCTION_TYPE_DEFAULT",
"functionType": "FUNCTION_TYPE_ANY",
"initialContent": {
"main.ts": "'$(base64 -w0 main.ts)'"
},
Expand Down Expand Up @@ -241,12 +241,16 @@ A function cannot be deleted if it is referenced by a hook. Remove or update any

### Invoke a function

<Note>
`json` is a `bytes` field, so its value must be base64-encoded — not a raw JSON string.
</Note>

```bash
curl -X POST "$C1_TENANT/api/v1/functions/$FUNCTION_ID/invoke" \
-H "Authorization: Bearer $C1_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"json": "{\"key\": \"value\"}"
"json": "'$(printf '{"key": "value"}' | base64 -w0)'"
}'
```

Expand Down
32 changes: 16 additions & 16 deletions product/admin/functions-automations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: "Use functions in automations"
og:title: "Use functions in automations"
description: "Add custom function steps to C1 automations to implement complex business logic, integrate with external systems, and make dynamic decisions in your workflows."
og:description: "Add custom function steps to C1 automations to implement complex business logic, integrate with external systems, and make dynamic decisions in your workflows."

Check warning on line 5 in product/admin/functions-automations.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions-automations.mdx#L5

Did you really mean 'automations'?
sidebarTitle: "Use functions in automations"

Check warning on line 6 in product/admin/functions-automations.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions-automations.mdx#L6

Did you really mean 'automations'?
---

<Warning>
Expand All @@ -17,12 +17,12 @@
3. Captures your return value for use by subsequent steps

<Tip>
**When writing functions for use in automations, remember:**

Check warning on line 20 in product/admin/functions-automations.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions-automations.mdx#L20

Did you really mean 'automations'?

- Your function doesn't need to know it's called from an automation. It receives JSON in, returns JSON out.
- The **automation UI** defines which CEL expressions map to which input keys.
- Your **return value** becomes available to subsequent automation steps via the step name (such as `checkTraining.approved`).
- Your **return value** becomes available to subsequent automation steps via `ctx.<step_name>` (such as `ctx.checkTraining.approved`).
- The function runs with the same security model regardless of trigger source: pre-authenticated SDK, egress allowlist, no filesystem.

Check warning on line 25 in product/admin/functions-automations.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions-automations.mdx#L25

Did you really mean 'allowlist'?
</Tip>

## Step 1: Add a function step to an automation
Expand Down Expand Up @@ -55,10 +55,10 @@

| Variable | Description |
|----------|-------------|
| `trigger.user_id` | User ID from the automation trigger |
| `trigger.app_id` | App ID from the trigger event |
| `trigger.entitlement_id` | Entitlement ID from the trigger |
| `previous_step_name.field` | Output field from a previously completed step |
| `ctx.trigger.user_id` | User ID from the automation trigger |
| `ctx.trigger.app_id` | App ID from the trigger event |
| `ctx.trigger.entitlement_id` | Entitlement ID from the trigger |
| `ctx.previous_step_name.field` | Output field from a previously completed step |

### Example inputs

Expand All @@ -68,8 +68,8 @@

| Key | CEL Expression |
|-----|----------------|
| `userId` | `trigger.user_id` |
| `appId` | `trigger.app_id` |
| `userId` | `ctx.trigger.user_id` |
| `appId` | `ctx.trigger.app_id` |
| `action` | `"verify"` (literal string) |

Your function receives the evaluated values:
Expand All @@ -86,8 +86,8 @@

| Key | CEL Expression |
|-----|----------------|
| `userId` | `steps.getUser.output.id` |
| `department` | `steps.getUser.output.profile.department` |
| `userId` | `ctx.getUser.id` |
| `department` | `ctx.getUser.profile.department` |
| `timestamp` | `now()` |

**Static values:**
Expand All @@ -104,9 +104,9 @@
The output of your function is available in subsequent steps via the step context. If your function step is named `checkTraining`, access its output like this:

```
steps.checkTraining.output.trainingCompleted
steps.checkTraining.output.eligible
steps.checkTraining.output.userId
ctx.checkTraining.trainingCompleted
ctx.checkTraining.eligible
ctx.checkTraining.userId
```

## Example: Training verification workflow
Expand Down Expand Up @@ -151,12 +151,12 @@

### Automation workflow

1. **Trigger:** Access request created
1. **Trigger:** Grant found (fires when a user is granted access to the app)
2. **Step 1: Run Function** `checkTraining`
- Input: `{ "userId": "trigger.user_id" }`
- Input: `{ "userId": "ctx.trigger.user_id" }`
3. **Step 2: Conditional** - Check if training is completed
- Condition: `steps.checkTraining.output.eligible == true`
- **If true:** Approve the access request
- Condition: `ctx.checkTraining.eligible == true`
- **If true:** No further action needed
- **If false:** Send notification to user with training link

## Best practices
Expand Down
6 changes: 3 additions & 3 deletions product/admin/functions-create.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

This guide walks you through creating your first function, from a simple "hello world" to accessing C1 data and calling external APIs.

## Use the copilot to write function code
## Use C1AI to write function code

Not sure where to start with TypeScript or the C1 API? The built-in AI code assistant can generate a working function from a plain-language description of what you want it to do — no TypeScript expertise required. Since functions start as drafts, you can try out the generated code, run it, and iterate safely before publishing.
Not sure where to start with TypeScript or the C1 API? [C1AI](/product/admin/ai-assistant) can generate a working function from a plain-language description of what you want it to do — no TypeScript expertise required. Since functions start as drafts, you can try out the generated code, run it, and iterate safely before publishing.

To get started, click **Create with AI** when creating a new function, or click **Edit with AI** in the code editor of an existing function draft. Describe what you want your function to do, and the AI assistant will generate code to get you started. You can then edit the code as needed, run it with test inputs, and publish when you're ready.
To get started, click **Create with Functions assistant** when creating a new function, or click **Edit with Functions assistant** in the code editor of an existing function draft. Describe what you want your function to do, and C1AI will generate code to get you started. You can then edit the code as needed, run it with test inputs, and publish when you're ready.

## Step 1: Set up a new function

Expand Down Expand Up @@ -354,7 +354,7 @@

## Best practices for writing functions

Follow these patterns to write maintainable, debuggable functions.

Check warning on line 357 in product/admin/functions-create.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions-create.mdx#L357

Did you really mean 'debuggable'?

### Use TypeScript interfaces

Expand Down
26 changes: 7 additions & 19 deletions product/admin/functions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Extend with custom code"
og:title: "Extend with custom code"
description: "Extend C1's identity governance capabilities with custom serverless TypeScript functions that integrate with external systems and implement organization-specific workflows."
og:description: "Extend C1's identity governance capabilities with custom serverless TypeScript functions that integrate with external systems and implement organization-specific workflows."

Check warning on line 5 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L5

Did you really mean 'serverless'?
sidebarTitle: "Extend with custom code"
---

Expand All @@ -12,12 +12,12 @@
**Early access.** This feature is in early access, which means it's undergoing ongoing testing and development while we gather feedback, validate functionality, and improve outputs. Contact the C1 Support team if you'd like to try it out or share feedback.
</Warning>

Functions are serverless TypeScript functions that extend C1's identity governance capabilities. Write custom automation logic, integrate with external systems, and implement organization-specific workflows that go beyond out-of-the-box features.

Check warning on line 15 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L15

Did you really mean 'serverless'?

## What you can do with functions

- **Call external systems**: Integrate with approved external APIs using a network allowlist

Check warning on line 19 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L19

Did you really mean 'allowlist'?
- **Run on events**: Trigger functions from automations using user lifecycle events, access changes, or schedules

Check warning on line 20 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L20

Did you really mean 'automations'?
- **Implement custom business logic**: Write your organization's unique workflows in TypeScript
- **Access C1 data**: Query users, apps, and entitlements through type-safe APIs

Expand All @@ -33,9 +33,9 @@

### Security and isolation

- Each function runs in isolation in a sandboxed environment

Check warning on line 36 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L36

Did you really mean 'sandboxed'?
- Functions authenticate to the C1 API as a [service principal](/product/admin/service-principals/overview) — its role bindings determine what the function can do at runtime
- Network allowlist controls which external domains functions can access

Check warning on line 38 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L38

Did you really mean 'allowlist'?
- Secrets management stores API keys securely, accessible via `functions.getConfig()`
- Execution logs capture `console.log` statements and stream back to the UI

Expand Down Expand Up @@ -77,28 +77,16 @@

## Key use cases for functions

Functions unlock powerful automation scenarios that go beyond standard workflows. Here are some examples of what they can do:
Functions unlock automation scenarios that go beyond standard workflows. Here are some examples of what they can do:

### Training and compliance verification
### Dynamic attribute generation

Verify users have completed required security training, background checks, or compliance certifications before granting access to sensitive apps. Functions can check external training systems via their APIs and automatically approve or reject access requests based on compliance status.

### Dynamic username generation

Generate unique usernames across multiple systems using complex naming conventions. Functions can implement your organization's username algorithm, check existing usernames for uniqueness, handle edge cases, and return a guaranteed-unique username.

### Custom approval routing

Route access requests to the right approver based on complex business rules. Functions can query your org chart, walk up the management chain to find VPs or specific roles, and determine the appropriate approver based on access sensitivity, user location, and app ownership.

### Risk scoring and conditional access

Calculate a risk score for access requests based on multiple factors (user role, data sensitivity, recent security incidents, login location) and auto-approve low-risk requests. Functions can aggregate data from multiple sources and implement your organization's risk-scoring algorithm.

### Integration with ticketing systems

Create tickets in Jira, ServiceNow, or other ITSM tools when access is granted, and update them when access is revoked or expires. Functions handle ticket system authentication, API rate limits, and bi-directional communication.
Generate and transform user attributes across systems — usernames, custom domain matching logic, attribute mapping translation tables, and other logic that goes beyond simple field mapping. Functions can implement your organization's naming conventions, check existing values for uniqueness, apply custom domain rules, and return computed values for use in provisioning.

### Custom notification and escalation

Send notifications via multiple channels (Slack, Teams, email, SMS) with custom formatting and escalation logic. Functions can format rich notifications with user and access context, implement retry logic, and track delivery.

### Out-of-band API calls

Call external APIs for provisioning-related tasks or other integrations that a connector invoked via automation can't handle. Functions manage authentication, rate limits, and response handling for these calls. If a system has an existing ConductorOne connector (such as Jira or ServiceNow), use that connector via automation instead of a function.

Check warning on line 92 in product/admin/functions.mdx

View check run for this annotation

Mintlify / Mintlify Validation (conductorone) - vale-spellcheck

product/admin/functions.mdx#L92

Did you really mean 'Jira'?