This section describes policy language features that let you grant more granular access.
Conditions
As part of a policy statement, you can specify one or more conditions that must be
met in order for access to be granted.
Each condition consists of one or more predefined variables that you specify values for in the policy statement. Later, when someone requests access to the resource in question, if the condition in the policy is met, it evaluates to true and the request is allowed. If the condition is not met, it evaluates to false and the request is not allowed.
There are two types of variables: those that are relevant to the request itself, and those relevant to the resource being acted upon in the request, also known as the target. The name of the variable is prefixed accordingly with either request or target followed by a period. For example, there's a request variable called request.operation to represent the API operation being requested. This variable lets you write a broad policy statement, but add a condition based on the specific API operation. For an example, see Let users write objects to Object Storage buckets.
Important
Condition matching is case insensitive. This is important to remember when writing conditions for resource types that allow case-sensitive naming. For example, the Object Storage service allows you to create both a bucket named "BucketA" and a bucket named "bucketA" in the same compartment. If you write a condition that specifies "BucketA", it will apply also to "bucketA", because the condition matching is case insensitive.
Variables that Aren't Applicable to a Request Result in a Declined Request 🔗
If the variable is not applicable to the incoming request, the condition evaluates to false and the request is declined. For example, here are the basic policy statements that together let someone add or remove users from any group except Administrators:
Allow group GroupAdmins to use users in tenancy
where target.group.name != 'Administrators'
Allow group GroupAdmins to use groups in tenancy
where target.group.name != 'Administrators'
Given the above policy, if GroupAdmins tried to call a general API operation for users such as ListUsers or UpdateUser (which lets you change the user's description), the request would be declined, even though those API operations are covered by use users.This is because the above policy statement for use users also includes the target.group.name variable, but the ListUsers or UpdateUser request doesn't involve specifying a group. There is no target.group.name for those requests, so the request is declined.
If you want to also grant access to general user API operations that don't involve a particular group, you would need an additional statement that gives the level of access you want to grant, but without the condition. For example, if you want to grant access to ListUsers, you need this additional statement:
Allow group GroupAdmins to inspect users in tenancy
Or if you want to grant access to UpdateUser, you need this additional statement (which also covers ListUsers because the use verb includes the capabilities of the inspect verb):
Allow group GroupAdmins to use users in tenancy
This general concept also applies to groups (for example, ListGroups and UpdateGroup), and any other resource type with target variables.
For more information about the syntax of conditions, see Conditions. For a list of all the variables you can use in policies, see the tables in the IAM Policies Overview.
Tag-Based Access Control 🔗
Using conditions and a set of tag variables, you can write policy to scope access based on the tags that have been applied to a resource. Access can be controlled based on a tag that exists on the requesting resource (the group or dynamic group in the policy) or on the target of the request (resource or compartment). Tag-based access control provides additional flexibility to your policies by allowing you to define access that spans compartments, groups, and resources. For details about how to write policies to scope access by tags, see Using Tags to Manage Access.
Permissions 🔗
Permissions are the atomic units of authorization that control a user's ability to perform operations on resources. Oracle defines all the permissions in the policy language. When you write a policy giving a group access to a particular verb and resource-type, you're actually giving that group access to one or more predefined permissions. The purposes of verbs is to simplify the process of granting multiple related permissions that cover a broad set of access or a particular operational scenario. The next sections give more details and examples.
Relation to Verbs 🔗
To understand the relationship between permissions and verbs, let's look at an example. A policy statement that allows a group to inspect volumes actually gives the group access to a permission called VOLUME_INSPECT (permissions are always written with all capital letters and underscores). In general, that permission enables the user to get information about block volumes.
As you go from inspect > read > use > manage, the level of access generally increases, and the permissions granted are cumulative. The following table shows the permissions included with each verb for the volumes resource-type. Notice that no additional permissions are granted going from inspect to read.
Each API operation requires the caller to have access to one or more permissions. For example, to use either ListVolumes or GetVolume, you must have access to a single permission: VOLUME_INSPECT. To attach a volume to an instance, you must have access to multiple permissions, some of which are related to the volumes resource-type, some to the volume-attachments resource-type, and some related to the instances resource-type:
VOLUME_WRITE
VOLUME_ATTACHMENT_CREATE
INSTANCE_ATTACH_VOLUME
The policy reference lists which permissions are required for each API operation. For example, for the Core Services API operations, see the table in Permissions Required for Each API Operation.
Understanding a User's Access 🔗
The policy language is designed to let you write simple statements involving only verbs and resource-types, without having to state the desired permissions in the statement. However, there may be situations where a security team member or auditor wants to understand the specific permissions a particular user has. The tables in the policy reference for each service show supported verbs and the associated permissions. You can look at the groups the user is in and the policies applicable to those groups, and from there compile a list of the permissions granted. However, having a list of the permissions isn't the complete picture. Conditions in a policy statement can scope a user's access beyond individual permissions (see the next section). Also, each policy statement specifies a particular compartment and can have conditions that further scope the access to only certain resources in that compartment.
Scoping Access with Permissions or API Operations 🔗
In a policy statement, you can use conditions combined with permissions or API operations to reduce the scope of access granted by a particular verb.
For example, let's say you want group XYZ to be able to list, get, create, or update groups (i.e., change their description), but not delete them. To list, get, create, and update groups, you need a policy with manage groups as the verb and resource-type. According to the table in Details for Verbs + Resource-Type Combinations, the permissions covered are:
GROUP_INSPECT
GROUP_UPDATE
GROUP_CREATE
GROUP_DELETE
To restrict access to only the desired permissions, you could add a condition that explicitly states the permissions you want to allow:
Copy
Allow group XYZ to manage groups in tenancy
where any {request.permission='GROUP_INSPECT',
request.permission='GROUP_CREATE',
request.permission='GROUP_UPDATE'}
An alternative would be a policy that allows all permissions except GROUP_DELETE:
Copy
Allow group XYZ to manage groups in tenancy where request.permission != 'GROUP_DELETE'
However, with this approach, be aware that any new permissions the service might add in the future would automatically be granted to group XYZ. Only GROUP_DELETE would be omitted.
Another alternative would be to write a condition based on the specific API operations. Notice that according to the table in Permissions Required for Each API Operation, both ListGroups and GetGroup require only the GROUP_INSPECT permission. Here's the policy:
Copy
Allow group XYZ to manage groups in tenancy
where any {request.operation='ListGroups',
request.operation='GetGroup',
request.operation='CreateGroup',
request.operation='UpdateGroup'}
It can be beneficial to use permissions instead of API operations in conditions. In the future, if a new API operation is added that requires one of the permissions listed in the permissions-based policy above, that policy will already control XYZ group's access to that new API operation.
But notice that you can further scope a user's access to a permission by also specifying a condition based on API operation. For example, you could give a user access to GROUP_INSPECT, but then only to ListGroups.
Copy
Allow group XYZ to manage groups in tenancy
where all {request.permission='GROUP_INSPECT',
request.operation='ListGroups'}
Scoping Policy by the IP Address of the Requestor 🔗
You can scope access to only a set of allowed IP addresses. For example, you can write policy to allow only requests from a given public IP range to access a specific Object Storage bucket; or, you can allow only specific subnets of a specific VCN to make requests over a service gateway.
To restrict access to a set of IP addresses, do the following:
Create a network source object that specifies the allowed IP addresses. See Managing Network Sources for details.
Write a policy that uses the network source object in a condition.
allow group GroupA to manage object-family in tenancy where request.networkSource.name='corpnet'
Restricting Access to Resources Based on Time Frame 🔗
You can use time-based variables in your policies to restrict the access granted in the
policy to only certain time frames. This feature allows you to restrict actions on
resources to particular times. For example, you can create a policy that allows access
only through a specified date. A policy like this would be useful if your company hires
contractors and you want to ensure access is not allowed past the contract end date. Or,
you could allow access to resources only during business hours (for example,
Monday-Friday 9:00 AM - 5:00 PM). This restriction can lower the risk of a bad actor
making changes when they are more likely to go unnoticed.
The variables that you can use to scope access based on time are:
request.utc-timestamp
request.utc-timestamp.month-of-year
request.utc-timestamp.day-of-month
request.utc-timestamp.day-of-week
request.utc-timestamp.time-of-day
Usage for these variables is described in more detail in the following sections.
Information for Working with Time-Based Variables 🔗
You must specify the time the variables using ISO 8601 format: YYYY-MM-DDThh:mm:ssZ. Examples of this
format are:
Date and time with seconds: '2020-04-01T15:00:00Z'
Data and time with minutes: '2020-04-01T05:00Z'
Date only: '2020-04-01Z'
Time only: '05:00:00'
Even though you can specify a time down to seconds, you should allow for a 5 minute
time difference between the timestamp on the request and the time the request is
evaluated by the IAM service. This time difference can be caused by several factors,
therefore be aware of this potential discrepancy when you plan and implement your
time-based policies.
The time that you specify is evaluated as Coordinated Universal Time (UTC). This
means that you must calculate the correct UTC time for the time zone in which the
policy is evaluated. For example, to specify 9:00 AM Pacific Standard Time for the
value of a variable, you would enter '17:00:00'. If your locale participates in
daylight savings, you'll need to update any policies that refer to a specific hour
when the time change goes into effect.
Details for Each Time-Based Variable 🔗
Usage for each variable is described in the following sections:
Description: The time the request is received for authorization. You can write
a policy that allows access only before or after a specific date-time timestamp. The
timestamp must follow the ISO 8601 format: YYYY-MM-DDThh:mm:ssZ and be in
Coordinated Universal Time (UTC).
Supported operators: before | after
Allowed values: Coordinated Universal Time (UTC) timestamp in ISO 8601 format: YYYY-MM-DDThh:mm:ssZ
Example Values:
'2020-04-01T00:00:00Z'
'2020-04-01T00:00Z'
Example policy: Allow group, Contractors, to access the
instance-family resources only until a certain date:
Copy
Allow group Contractors to manage instance-family in tenancy where request.utc-timestamp before '2022-01-01T00:00Z'
The access granted by the policy to the group Contractors will expire on January 1,
2022, 12:00 AM, UTC.
Description: The month of the year that the request is received for
authorization. You can write a policy that allows access only during specific
months.
Description: The day of the month that the request is received for
authorization. You can write a policy that allows access only for specific days of
the month. Keep in mind that the span of the day is calculated based on UTC. For
example, suppose you are in Miami, FL, USA, and you enter '1' to indicate the first
day of the month. For the month of February, the policy will be in effect for 12:00
AM through 11:59 PM UTC on February 1, which in Miami is 7:00 PM on January 31
through 6:59 PM on February 1.
Supported operators: = | != | in
Allowed values: Numeric day of month
Example Values: '1', '2', '3', ... '31'
Example policy: Allow group, ComplianceAuditors, to read
all-resources only on the first day of the month.
Copy
Allow group ComplianceAuditors to read all-resources in tenancy where request.utc-timestamp.day-of-month = '1'
The access granted by the policy to the group ComplianceAuditors is only valid on the
first day of each month (the day is defined by UTC time).
Description: The day of the week that the request is received for
authorization. You can write a policy that allows access only for specific days of
the week. Note that the span of the day is calculated based on UTC. For example,
suppose you are in Miami, FL, USA, and you enter 'monday'. The policy will be in
effect for 12:00 AM through 11:59 PM UTC on Monday, which in Miami is 7:00 PM (EST)
on Sunday through 6:59 PM on Monday.
Supported operators: = | != | in
Allowed values: Name of day of week in English
Example Values: 'Monday', 'Tuesday', 'Wednesday', etc.
Example policy: Allow group, WorkWeek, to
manageinstance-family only during the company work week.
Copy
Allow group WorkWeek to manage instance-family where ANY {request.utc-timestamp.day-of-week in ('monday', 'tuesday', 'wednesday', 'thursday', 'friday')}
The access granted by the policy to the group WorkWeek is only valid on the days
specified (the day is defined by UTC time).
Description: The time of day that the request is received for authorization.
You can write a policy that allows access only for a specific span of time during
the day. Note that the time of the day is calculated based on UTC. If you live in a
time zone that implements daylight savings, you will need to update the policy when
the time changes.
Supported operators: between
Allowed values: UTC time interval in ISO 8601 format: hh:mm:ssZ
Example Values: '01:00:00Z' AND '2:01:00Z'
Example policies: Allow group DayShift to manage instances and related
resources between the hours of 9:00 AM and 5:00 PM Pacific Standard Time (PST).
Note that the times are converted to UTC:
Copy
Allow group DayShift to manage instance-family where request.utc-timestamp.time-of-day between '17:00:00Z' and '01:00:00Z'
I want to allow group NightShift to manage instances and related resources between
5:00 PM and 9:00 AM PST.
Copy
Allow group NightShift to manage instance-family where request.utc-timestamp.time-of-day between '01:00:00Z' and '17:00:00Z'
In both of these examples, the current time is calculated and tested to see if it
falls within the provided range or not (ignoring which day the time falls on).