> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

Automate self-service action approvals

Implement with AI

Send this guide to your coding agent.

Prerequisite: Install Port MCP

Open plan mode if your tool supports it; otherwise present the plan below filled in and wait for my approval. Implement this Port guide in my org via MCP:

https://docs.port.io/guides/all/automatically-approve-action-using-automation

Read the raw markdown version at https://docs.port.io/guides/all/automatically-approve-action-using-automation.md - it contains every tab and code block without page markup.

Goal: get the guide's core flow working end-to-end in my org; adapting it to fit my existing setup takes priority over matching the guide 1:1.

Plan:
1. Confirm MCP is connected, in the right org, with sufficient permissions.
2. If the guide offers alternative implementation paths (tabs), pick the one matching my installed integrations and tools, confirm it with me, and implement only that path.
3. Diff the guide's data model (blueprints, properties, relations, workflows, actions, agents, automations, integrations, webhook data sources, secrets) against mine.
4. Propose adaptations for gaps, reusing existing blueprints/relations over guide-named duplicates.
5. Flag what needs a UI click, credential, or secret from me, testing MCP capability empirically before ruling anything out. If the guide has a "Set up via API" section, use it for anything MCP can't do before treating a step as UI-only.
6. Stop on any blocker and give me options. Approving this plan authorizes the writes it lists; pause only for writes beyond what's listed.

Build:
- Extend blueprint schema additively when upserting; don't remove or overwrite existing properties, and treat type conflicts as a blocker, not an auto-fix.
- Never print secret values into the chat or logs; ask me to set them in Port, or write them via the secrets API without echoing them back.
- List any mock data in the plan, minimal and labeled mock; once approved, seed it without re-asking, and tell me what you seeded.
- For anything the guide writes downstream (e.g. a webhook target), use a real entity, not a mock.
- For pages/widgets, use the real page identifier from the app URL, not a guessed slug.
- When you hit a UI step confirmed (not assumed) unsupported via MCP and not covered by the guide's API sections, pause, give exact clicks, then resume via MCP.
- Validate and give links after each meaningful step (only a tool-returned URL, no guessed paths); don't proceed if the last run wasn't a success.

Done:
- Run the guide's "Let's test it" steps where possible (e.g. execute a workflow test run) and confirm the expected output exists in Port.
- Summarize adaptations, seeded data, what was mocked or skipped, remaining UI steps, and how to verify.

In this guide, we will walk you through the process of setting up an automated approval system for self service actions. We will use a specific example of a developer requesting a cloud resource, such as a database, with a certain level of permissions.

Prerequisites

Before we begin, make sure you have:

  • Access to your Port account.
  • Permissions to create and edit self service actions and automations.

Create the self-service action

Let's start by creating a self service action for requesting permissions:

  1. Navigate to the Self-service page in Port.
  2. Click on + Action to create a new self service action.
  3. Use the following JSON structure for your action:
Request Database Access (click to expand)
{
"identifier": "request_permissions",
"title": "Request Database Access",
"trigger": {
"type": "self-service",
"operation": "CREATE",
"userInputs": {
"properties": {
"permissions": {
"type": "string",
"title": "Permissions",
"enum": [
"ReadOnly",
"ReadWrite"
],
"enumColors": {
"ReadOnly": "lightGray",
"ReadWrite": "lightGray"
}
},
"reason": {
"type": "string",
"title" : "Reason for Requesting Permission"
}
},
"required": [],
"order": []
}
},
"invocationMethod": {
"type": "SLACK",
"url": "https://hooks.slack.com/services/xyz", //Replace this with your slack webhook url
"agent": false,
"synchronized": true,
"method": "POST",
"headers": {},
"body": {
"text": "hello from Port :slightly_smiling_face:, {.trigger.by.user.email} from your organization has requested access to a database. The reason: {.payload.properties.reason}"
}
},
"requiredApproval": {
"type": "ANY"
},
"approvalNotification": {
"type": "email"
}
}

This self service configuration does the following:

  • Defines an action with the identifier "request_permissions".
  • Sets up user inputs for selecting permission types (ReadOnly or ReadWrite).
  • Configures a Slack webhook invocation method to notify about new requests.
  • Specifies that approval is required.
  • Sets up email notifications for approvals.

Set up the automation

Now that we have our self service action, let's create an automation that will approve certain requests:

  1. In the Automations page, click on + Automation.
  2. Use the following JSON structure for your automation:
Automation definition - auto approve cloud resources (click to expand)
{
"identifier": "auto-approve",
"title": "Auto Approve Cloud Resource Access",
"description": "Auto Approve",
"trigger": {
"type": "automation",
"event": {
"type": "RUN_CREATED",
"actionIdentifier": "request_permissions"
},
"condition": {
"type": "JQ",
"expressions": [
".diff.after.properties.permissions == \"ReadOnly\""
],
"combinator": "and"
}
},
"invocationMethod": {
"type": "WEBHOOK",
"url": "https://api.port.io/v1/actions/runs/{{ .event.diff.after.id }}/approval",
"agent": false,
"synchronized": true,
"method": "PATCH",
"headers": {},
"body": {
"status": "APPROVE",
"description": "auto approved by automation"
}
},
"publish": true
}

This automation configuration:

  • Triggers when a new run of the "request_permissions" action is created.
  • Checks if the requested permission type is "ReadOnly".
  • If the condition is met, it automatically approves the request via Port's API.

How It Works

When a user submits a permissions request:

  • If they select ReadOnly, the automation triggers and automatically approves the request.
  • If they select ReadWrite, the automation doesn't trigger, and the request requires manual approval.

The automation uses a JQ expression to check the permission type:

.diff.after.properties.permissions == "ReadOnly"

When the condition is met, it sends a PATCH request to Port's API to approve the action run.

Customize the automation

You can customize the automation to fit your specific needs:

  • Modify the condition: Change the JQ expression to check for different properties or values.
  • Add multiple conditions: Use the combinator field to combine multiple expressions with "and" or "or" logic.
  • Customize the approval message: Modify the description in the webhook body to provide more context.

Conclusion

By leveraging Port's automation capabilities, we have created an efficient, secure workflow that reduces manual overhead for permission requests. This system streamlines the approval process for ReadOnly permissions while ensuring that ReadWrite requests still go through manual review.