Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve documentation for scoped tokens #1352

Merged
merged 4 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified sources/platform/integrations/images/api-token-scoped-run-modes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
63 changes: 51 additions & 12 deletions sources/platform/integrations/programming/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@

### Allowing tokens to create resources

If you need to create new resources with the token (for example, create a new Task, or storage), you need to explicitly allow that as well.
If you need to create new resources with the token (for example, create a new task, or storage), you need to explicitly allow that as well.

Once you create a new resource with the token, _the token will gain full access to that resource_, regardless of other permissions. It is not possible to create a token that can create a dataset, but not write to it.

Expand All @@ -94,19 +94,21 @@

#### Automatic dependencies

The form enforces certain dependencies automatically. For example, when you grant the _Write_ permission for a dataset, the _Read_ permission is automatically selected. This ensures that you can write to a dataset if you can also read from it.
The form enforces certain dependencies automatically. For example, when you grant the `Write` permission for a dataset, the `Read` permission is automatically selected. This ensures that you can write to a dataset if you can also read from it.
tobice marked this conversation as resolved.
Show resolved Hide resolved

![The Write permission depends on Read for a dataset](../images/api-token-scoped-dependencies.png)

#### Manual dependencies

Other dependencies are more complicated, and **it is your responsibility that the token is set up correctly**. Specifically:
Other dependencies are more complicated, so it is up to you to ensure that the token is configured correctly.

- To create or update a Schedule, the token needs access not only to the Schedule itself, but also to the Actor or task that is being scheduled.
- Similarly, to create or update a task, the token needs the additional permission to access the task's Actor itself.
Specifically:

- To create or update a Schedule, the token needs access not only to the Schedule itself, but also to the Actor (the `Run` permission) or task (the `Read` permission) that is being scheduled.
- Similarly, to create, update or run a task, the token needs the `Run` permission on the task's Actor itself.
tobice marked this conversation as resolved.
Show resolved Hide resolved

:::tip
Let's say that you have an Actor and you want to programmatically create schedules for that Actor. Then you can create a token that has the account level _Create_ permission on schedules, but only the resource-specific _Run_ permission on the Actor. Such a token has exactly the permissions it needs, and nothing more.
Let's say that you have an Actor and you want to programmatically create schedules for that Actor. Then you can create a token that has the account level `Create` permission on schedules, but only the resource-specific `Run` permission on the Actor. Such a token has exactly the permissions it needs, and nothing more.
tobice marked this conversation as resolved.
Show resolved Hide resolved
:::

### Actor execution
Expand All @@ -117,8 +119,8 @@

Apify currently supports two modes:

- **Full access**: Allow Actors to access all your account's data.
- **Restricted access**: Restrict what Actors can access using the scope of this Actor.
- `Full access`: Allow Actors to access all your account's data.
- `Restricted access`: Restrict what Actors can access using the scope of this Actor.
tobice marked this conversation as resolved.
Show resolved Hide resolved

![Choose permission mode for running Actors with a scoped token](../images/api-token-scoped-run-modes.png)

Expand Down Expand Up @@ -146,8 +148,20 @@

When Apify [runs an Actor](/platform/actors/running/runs-and-builds#runs), it automatically creates a set of default storages (a dataset, a key-value store and request queue) that the Actor can use in runtime.

- Regardless of mode, the injected token always gets write access to its default storages, and to the run itself (for example, so that the Actor can abort itself). You don't need to configure this on your scoped token.
- If a scoped token can run an Actor, it gets **write access to default storages of the runs it triggered**. Moreover, it gets **read access to default storages of _all_ runs of that Actor**. If this is not desirable, change your Actor to output data into an existing named storage, or have it create a new storage.
You can configure whether the scoped token you are going use to run the Actor should get _write_
tobice marked this conversation as resolved.
Show resolved Hide resolved
tobice marked this conversation as resolved.
Show resolved Hide resolved
access to these default storages.

![Configure whether the trigger token gets write access to the run default storages.](../images/api-token-scoped-default-storage-access.png)

:::tip
Let's say your Actor produces a lot of data that you want to delete just after the Actor finishes. If you enable this toggle, your scoped token will be allowed to do that.
:::

:::caution
Even if you disable this option, **the default storages can still be accessed anonymously using just their ID** (which can be obtained via the [run object](https://docs.apify.com/api/v2#tag/Actor-runsRun-object-and-its-storages)).

Moreover, if a scoped token can run an Actor, it can also list all its runs, including their storage IDs, ultimately exposing their content as well. If this is not desirable, change your Actor to output data into an existing named storage, or have it create a new storage.
:::

### Schedules

Expand All @@ -164,7 +178,32 @@
Therefore, you need to make sure the token has sufficient permissions not only to set up the webhook, but also to perform the actual operation.

:::tip

Let's say you want to create a webhook that pushes an item to a dataset every time an Actor successfully finishes. Then such a scoped token needs to be allowed to both run the Actor (to create the webhook), and write to that dataset.

:::

### Troubleshooting

#### How do I allow a token to run a task?
tobice marked this conversation as resolved.
Show resolved Hide resolved

There is no dedicated run permission for tasks. Instead, configure the token with the following permissions:

Check failure on line 188 in sources/platform/integrations/programming/api.md

View workflow job for this annotation

GitHub Actions / lint

[vale] reported by reviewdog 🐶 [write-good.ThereIs] Don't start a sentence with 'There is'. Raw Output: {"message": "[write-good.ThereIs] Don't start a sentence with 'There is'.", "location": {"path": "sources/platform/integrations/programming/api.md", "range": {"start": {"line": 188, "column": 1}}}, "severity": "ERROR"}
tobice marked this conversation as resolved.
Show resolved Hide resolved
tobice marked this conversation as resolved.
Show resolved Hide resolved

- `Run` on the Actor that the task is executing
tobice marked this conversation as resolved.
Show resolved Hide resolved
- `Read` on the task
tobice marked this conversation as resolved.
Show resolved Hide resolved

See the example below:
tobice marked this conversation as resolved.
Show resolved Hide resolved

![Scoped token configured to run a task](../images/api-token-scoped-run-tasks.png)

Refer to [this section](#permission-dependencies) to understand how permission dependencies work.

#### My run failed and I can see `insufficient permissions` in the logs
tobice marked this conversation as resolved.
Show resolved Hide resolved

You probably run the Actor using a scoped token with `Restricted access` configured.
tobice marked this conversation as resolved.
Show resolved Hide resolved

![Scoped token with Restricted access](../images/api-token-scoped-restricted-access-active.png)

What is happening is that the Actor is trying to access a resource (such a dataset, or a key-value store) or perform an operation that it does not have sufficient permissions for.
tobice marked this conversation as resolved.
Show resolved Hide resolved

If you know what it is, you can add the permission to the scope of your token. If you don't, you can switch the permission mode on the token to `Full access`. This means that the Actor will be able to access all your account data.
tobice marked this conversation as resolved.
Show resolved Hide resolved

Refer to [this section](#actor-execution) to understand how executing Actors with scoped tokens works.
tobice marked this conversation as resolved.
Show resolved Hide resolved
Loading