diff --git a/pages/iam/assets/scaleway-iam-create-policy-1.webp b/pages/iam/assets/scaleway-iam-create-policy-1.webp
index 9715694ccc..bb286c99ec 100644
Binary files a/pages/iam/assets/scaleway-iam-create-policy-1.webp and b/pages/iam/assets/scaleway-iam-create-policy-1.webp differ
diff --git a/pages/iam/assets/scaleway-iam-create-policy-2.webp b/pages/iam/assets/scaleway-iam-create-policy-2.webp
index 756c043879..6cd4934356 100644
Binary files a/pages/iam/assets/scaleway-iam-create-policy-2.webp and b/pages/iam/assets/scaleway-iam-create-policy-2.webp differ
diff --git a/pages/iam/concepts.mdx b/pages/iam/concepts.mdx
index b5370cc7d2..9d20fc51cb 100644
--- a/pages/iam/concepts.mdx
+++ b/pages/iam/concepts.mdx
@@ -32,6 +32,14 @@ Previously, an API key was associated with a single Scaleway [Project](#project)
With the introduction of IAM, an API key is now associated with an IAM [user](#user) or [application](#application). This allows fine-grained access to be defined for the IAM user bearing the API key across different Organizations, Projects, and resources.
+## Common Expression Language (CEL)
+
+The Common Expression Language (CEL) is used to define expressions in [conditions](#conditions) within an IAM policy. CEL allows you to create attribute-based logic expressions that determine whether specific permissions apply. A condition expression typically consists of one or more statements, each defining an attribute-based control rule. IAM conditions use the following CEL features: **Variables**, **Operators**, **Functions**, and **Logical Operators**. Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page for a detailed description of the supported CEL features.
+
+## Conditions
+
+A condition is an additional layer of restrictions for your rule. You can allow access to specific user agents or IP addresses, and allow actions to be performed only at certain dates and times. Conditions are defined through [CEL](#common-expression-language-cel) expressions, and can be set up and configured in the Scaleway console. Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page to learn how they are set up and how you can define them.
+
## Group
A group (also known as an IAM group) is a grouping of [users](#user) and/or [applications](#application). Creating groups allows you to attach [policies](#policy) to multiple users and/or applications at the same time.
@@ -91,8 +99,6 @@ Policies control user rights by defining one or more [rules](#rule) to apply to
For each policy rule, you specify one or more permission sets (e.g. "list all Instances") and their scope (e.g. "on Project A only"). This therefore defines the actions that the principles can carry out on resources within the scope.
-
-
## Preferred Project
You can carry out actions on Scaleway Object Storage resources either via the [Scaleway console](https://console.scaleway.com), or via a third-party API or CLI, such as [the AWS CLI](/object-storage/api-cli/object-storage-aws-cli/), [MinIOClient](/object-storage/api-cli/installing-minio-client/) or [Rclone](/object-storage/api-cli/installing-rclone/). While the Scaleway console gives you the option to specify the [Scaleway Project](/organizations-and-projects/concepts/#project) to carry out your Object Storage actions in, this option is not available via third-party API/CLI tools. These tools are based on a [standard Amazon S3 programming interface](https://en.wikipedia.org/wiki/Amazon_S3#S3_API_and_competing_services), which does not accept Project ID as a parameter. Therefore, when you create a Scaleway API key with IAM, you are prompted to specify the API key's **preferred Project for Object Storage**. This API key will always use this Project when carrying out Object Storage actions via any API/CLI. See our page on [using API keys with Object Storage](/iam/api-cli/using-api-key-object-storage/) for more information.
diff --git a/pages/iam/how-to/assets/scaleway-create-policy-p1.webp b/pages/iam/how-to/assets/scaleway-create-policy-p1.webp
deleted file mode 100644
index 21ea49f611..0000000000
Binary files a/pages/iam/how-to/assets/scaleway-create-policy-p1.webp and /dev/null differ
diff --git a/pages/iam/how-to/assets/scaleway-create-policy-p2.webp b/pages/iam/how-to/assets/scaleway-create-policy-p2.webp
deleted file mode 100644
index 9a72cab943..0000000000
Binary files a/pages/iam/how-to/assets/scaleway-create-policy-p2.webp and /dev/null differ
diff --git a/pages/iam/how-to/assets/scaleway-iam-create-policy-1.webp b/pages/iam/how-to/assets/scaleway-iam-create-policy-1.webp
new file mode 100644
index 0000000000..bb286c99ec
Binary files /dev/null and b/pages/iam/how-to/assets/scaleway-iam-create-policy-1.webp differ
diff --git a/pages/iam/how-to/assets/scaleway-iam-create-policy-2.webp b/pages/iam/how-to/assets/scaleway-iam-create-policy-2.webp
new file mode 100644
index 0000000000..6cd4934356
Binary files /dev/null and b/pages/iam/how-to/assets/scaleway-iam-create-policy-2.webp differ
diff --git a/pages/iam/how-to/assets/scaleway-policy-overview.jpg b/pages/iam/how-to/assets/scaleway-policy-overview.jpg
new file mode 100644
index 0000000000..1ad5aef66b
Binary files /dev/null and b/pages/iam/how-to/assets/scaleway-policy-overview.jpg differ
diff --git a/pages/iam/how-to/assets/scaleway-policy-overview.webp b/pages/iam/how-to/assets/scaleway-policy-overview.webp
deleted file mode 100644
index ef849e42dc..0000000000
Binary files a/pages/iam/how-to/assets/scaleway-policy-overview.webp and /dev/null differ
diff --git a/pages/iam/how-to/create-policy.mdx b/pages/iam/how-to/create-policy.mdx
index ee01eae581..8e7ab11833 100644
--- a/pages/iam/how-to/create-policy.mdx
+++ b/pages/iam/how-to/create-policy.mdx
@@ -42,19 +42,24 @@ An IAM [policy](/iam/reference-content/policy/) is used to define the permission
5. Click **Add rules** to progress to the next part of the policy creation wizard.
- Rules define the actions that the attached principal will be able to carry out within the Organization. When creating a rule, you first set the **scope** of the rule, and then select the **permission sets** to apply within the scope. See our dedicated documentation for more help with [policies, rules, scopes and permission sets](/iam/reference-content/policy/).
+ Rules define the actions that the attached principal will be able to carry out within the Organization. When creating a rule, you first set the **scope** of the rule, and then select the **permission sets** to apply within the scope. You can optionally set up **conditions** for your rule. See our dedicated documentation for more help with [policies, rules, scopes and permission sets](/iam/reference-content/policy/).
6. Select a **scope** for the rule:
- To give the principal permissions to view, create, edit and/or delete [resources](/iam/concepts/#resource), select the **Access to resources** scope. Then, select the [Project](/iam/concepts/#project) in which you want the permissions to apply. You can select from **all current and future Projects**, **all current Projects** or select specific Projects.
- To give the principal permissions to [Organization](/iam/concepts/#organization)-level features such as IAM, billing, support & abuse tickets and project management, select the **Access to Organization features** scope.
7. Click **Validate** to continue.
8. Choose the **permission sets** for the rule by selecting the required boxes. You can select as many permission sets as you like. The principal will have the rights defined in these permission sets within the scope you set in **step 6**. See our dedicated documentation for [more help with permission sets](/iam/reference-content/permission-sets/).
-9. Click **Validate**. The rule, with its scope and permission sets, is added to the list of the policy's rules.
-10. Click **Add new rule** and repeat steps 6-8 as many times as required to add multiple rules to your policy.
+9. Click **Validate**.
+10. (Optional) Click **+ Add new** to add one or more conditions. You can allow access to specific user agents or IP addresses, and allow actions to be performed only at certain dates and times.
+
+ Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page for more details about how to write condition expressions, as well as examples of conditions.
+
+11. Click **Validate**. The rule, with its scope and permission sets, is added to the list of the policy's rules.
+12. Click **Add new rule** and repeat steps 6 to 8 as many times as required to add multiple rules to your policy.
You can delete or edit an existing rule by clicking the relevant button in the top right corner of the rule's summary.
-11. Click **Create policy** to finish.
+13. Click **Create policy** to finish.
You are returned to the **Policies** tab, where the newly-created policy now appears in the list.
diff --git a/pages/iam/how-to/manage-policies.mdx b/pages/iam/how-to/manage-policies.mdx
index 9df26a2613..a296cf5c56 100644
--- a/pages/iam/how-to/manage-policies.mdx
+++ b/pages/iam/how-to/manage-policies.mdx
@@ -38,7 +38,11 @@ From the policy's [Overview page](#how-to-access-the-policy-overview):
## How to edit a policy's rules
1. From the policy's [Overview page](#how-to-access-the-policy-overview), scroll down to the **Rules** panel and click next to the rule you want to edit.
-2. Edit the rule as required, and click **Validate** to finish.
+2. Edit the rule as required. You can edit the scope, permission sets and conditions.
+
+ Conditions can only be edited using the **Advanced** editor. You must update the [CEL](/iam/concepts#common-expression-language-cel) expression in the editor to update the condition. Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page for more details about how to write condition expressions, as well as examples of conditions.
+
+3. Click **Validate** to finish.
See our documentation about [creating policies](/iam/how-to/create-policy/) for more help with building rules.
diff --git a/pages/iam/quickstart.mdx b/pages/iam/quickstart.mdx
index 919d0be34b..df9ef44387 100644
--- a/pages/iam/quickstart.mdx
+++ b/pages/iam/quickstart.mdx
@@ -77,11 +77,20 @@ Users you have invited to your Organization, and applications you have created,
- To give the principal permissions to [Organization](/iam/concepts/#organization)-level features such as IAM, billing, support & abuse tickets and project management, select the **Access to Organization features** scope.
7. Click **Validate** to continue.
8. Choose the **permission sets** for the rule by selecting the required boxes. You can select as many permission sets as you like. The principal will have the rights defined in these permission sets within the scope you set in **step 6**. See our dedicated documentation for [more help with permission sets](/iam/reference-content/permission-sets/).
-9. Click **Validate**. The rule, with its scope and permission sets, is added to the list of the policy's rules.
-10. Click **Add new rule** and repeat steps 6-8 as many times as required to add multiple rules to your policy.
+9. Click **Validate**.
+10. (Optional) Click **+ Add new** to add one or more conditions. You can allow access to specific user agents or IP addresses, and allow actions to be performed only at certain dates and times.
+
+ Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page for more details about how to write condition expressions, as well as examples of conditions.
+
+11. Click **Validate**. The rule, with its scope and permission sets, is added to the list of the policy's rules.
+12. Click **Add new rule** and repeat steps 6 to 8 as many times as required to add multiple rules to your policy.
You can delete or edit an existing rule by clicking the relevant button in the top right corner of the rule's summary.
-11. Click **Create policy** to finish.
+13. Click **Create policy** to finish.
- You are returned to the **Policies** tab, where the newly-created policy now appears in the list.
\ No newline at end of file
+ You are returned to the **Policies** tab, where the newly-created policy now appears in the list.
+
+
+ The application of Object Storage permissions can take up to 5 minutes.
+
\ No newline at end of file
diff --git a/pages/iam/reference-content/policy.mdx b/pages/iam/reference-content/policy.mdx
index 9d0761c2ae..194096214d 100644
--- a/pages/iam/reference-content/policy.mdx
+++ b/pages/iam/reference-content/policy.mdx
@@ -19,8 +19,7 @@ They are composed of:
- a [principal](#principal) - a user, group, or application,
- one or more IAM rules - consisting of [permission sets](#permission-sets) bound to a [scope](#scope).
-
-
+- one or more IAM conditions - defined in Common Expression Language (CEL) expressions.
## Principal
@@ -55,6 +54,14 @@ A permission set consists of one or multiple permissions to perform actions on r
You can find a detailed list of all permission sets available at Scaleway in the permission sets [reference page](/iam/reference-content/permission-sets/).
+### Conditions
+
+A condition is an additional layer of restrictions for your rule. You can allow access to specific user agents or IP addresses, and allow actions to be performed only at certain dates and times. Conditions are defined through [CEL](#common-expression-language-cel) expressions. In general, a condition expression consists of one or more statements that are joined by logical operators (`&&`, `||`, or `!`).
+
+Conditions can be set up and configured in the Scaleway console.
+
+Refer to the [Understanding policy conditions](/iam/reference-content/understanding-policy-conditions) documentation page to learn how they are set up and how you can define them.
+
### Example rule
The rule below defines various levels of access to different resources in Project A.
diff --git a/pages/iam/reference-content/understanding-policy-conditions.mdx b/pages/iam/reference-content/understanding-policy-conditions.mdx
new file mode 100644
index 0000000000..b019a47d4e
--- /dev/null
+++ b/pages/iam/reference-content/understanding-policy-conditions.mdx
@@ -0,0 +1,140 @@
+---
+meta:
+ title: Understanding policy conditions
+ description: Detailed information on policy conditions within Scaleway IAM.
+content:
+ h1: Understanding policy conditions
+ paragraph: Learn how to use policy conditions to fine-tune access control within Scaleway IAM.
+tags: iam
+dates:
+ validation: 2025-03-03
+categories:
+ - iam
+ - console
+---
+
+A condition is an additional layer of restrictions for your rule. You can configure conditions in IAM policies to allow access to specific user agents, IP addresses and on a given date or time.
+
+At Scaleway, IAM conditions are defined using Common Expression Language (CEL) expressions.
+
+
+ Refer to the [How to create a policy](/iam/how-to/create-policy/) and [How to manage policies](/iam/how-to/create-policy/) documentation pages to learn where and how to specify a condition.
+
+
+## Condition expressions
+
+An expression can be compared to a conditional statement in programming. It is a logical statement that evaluates to either true or false. The result determines whether the permission set defined in the rule is applied or not.
+
+Condition expressions are composed of one or several statements that declare a rule based on attributes. Attributes are like characteristics or properties of a request, resource or a user. For example, an attribute might be a given date or time, or an IP address.
+
+
+ Currently only request-based conditions are available with Scaleway IAM.
+
+
+Expressions at Scaleway are defined in CEL, which provides a human-readable and flexible method of creating conditions.
+
+## Common Expression Language
+
+Common Expression Language is used to specify a IAM condition expression.
+
+Expressions consist of one or more statements that declare an attribute-based control rule, and determine whether a permission applies.
+
+IAM conditions use the following CEL features:
+ - Variables
+ - Operators and Logical Operators
+ - Functions
+
+### Variables
+
+Conditions use variables to express attributes. Variables are populated with values based on the context at runtime.
+
+| Name | Type | Description |
+| ------------ | ------------------- | ------ |
+| `request.ip` | String | The IP address of the request. |
+| `request.time` | `google.protobuf.Timestamp` | The time of the request. Represented as a Protobuf object, allowing usage with [associated functions](https://github.com/google/cel-spec/blob/master/doc/langdef.md#datetime-functions).|
+| `request.user_agent` | String | The user-agent of the request. Truncated at 255 characters max.|
+
+### Operators
+
+Every data type, such as `timestamp` or `string`, supports a set of operators that can be used to create a logic expression.
+
+Most commonly, operators are used to compare the value contained in a variable with a literal value.
+
+For example, `==` is the operator in the following statement:
+
+```
+request.time == "2025-03-03T14:30:00.000Z"
+```
+
+Refer to the official [CEL syntax specification](https://github.com/google/cel-spec/blob/master/doc/langdef.md#syntax) for list of supported operators.
+
+#### Logical operators
+
+Conditions support three logical operators that can be used to build complex logic expressions from basic expression statements:
+
+| Logical operator | Description | Example |
+| -- | ------------------- | ------ |
+| `&&` (AND) | Evaluates to true if both expressions are true. | `request.time.getFullYear() < 2020 && request.ip == '10.154.3.1'` |
+| `\|\|` (OR) | Evaluates to true if either expression is true. If the first expression is true, the second expression may not be evaluated. | `request.time.getFullYear() < 2020 \|\| request.ip == '10.154.3.1'` |
+| `!` (NOT) | Evaluates to true if the expression is false, and false if the expression is true. | `!(request.time.getFullYear() < 2020)` |
+
+
+### Functions
+
+A function is a compound operator for data types, that supports more complex operations. In condition expressions, predefined functions can be used with a given data type.
+
+All standard CEL functions are supported, as well as the following custom Scaleway IAM function(s):
+
+| Function | Description | Parameters |
+| ------------ | ------------------- | ------ |
+| `inIpRange(IP: string, Subnet: string)` | Checks if the IP address is included in the IP subnet. | **IP**: (String) The IP address to check. |
+| | | **Subnet**: (String) The IP subnet to check against. |
+
+
+## Important considerations
+
+### Multiple policies
+If multiple policies with different conditions apply to the same principal, the presence of a single policy with met conditions (or no conditions) will override any denying rules from other policies, allowing the action to be taken.
+
+For example, if you set up a policy that grants access to a resource only on Monday while another policy grants access only on Tuesday, the action will still be allowed on Monday. The access will be granted on both days.
+
+### Timezones
+
+We recommend that you specify timezones when creating time-based conditions.
+
+Refer to the official [CEL specification](https://github.com/google/cel-spec/blob/master/doc/langdef.md#timezones) for the correct syntax to express timezones in conditions.
+
+### Timestamps
+
+Conditions based on timestamps might take up to a minute to be applied.
+
+For example, if a user has permission to perform an action until 11am, they may be able to perform it until 11:01am.
+
+### IAM condition limitations
+
+Currently it is only possible to edit conditions in the console using the **Advanced** expression editor.
+
+When creating a policy, you can define a simple condition expression with the help of the console form. When editing, you must define the changes by writing them in CEL in the Advanced editor.
+
+## Expression examples
+
+### User-agent conditions
+
+In the example below we check if the user-agent contains the term "Terraform":
+```
+request.user_agent.contains("terraform/")
+```
+
+### Time conditions
+
+To only allow actions within a specific timeslot you can use the following expression. In this example, use weekdays from 9am to 5pm as a timestamp.
+```
+request.time.getDayOfWeek() != 0 && request.time.getDayOfWeek() != 6
+&& request.time.getHours("Europe/Paris") < 17
+&& request.time.getHours("Europe/Paris") > 8
+```
+
+To only allow requests that were performed over the weekend, you can use the expression below:
+```
+request.time.getDayOfWeek() != 0 && request.time.getDayOfWeek() != 6
+```
\ No newline at end of file