Cette page explique comment utiliser les limites d'accès aux identifiants pour réduire ou restreindre les autorisations IAM (Identity and Access Management) qu'un identifiant de courte durée peut utiliser.
Vous pouvez utiliser les limites d'accès aux identifiants pour générer des jetons d'accès OAuth 2.0 qui représentent un compte de service, mais qui disposent de moins d'autorisations que le compte de service. Par exemple, si l'un de vos clients doit accéder aux données Cloud Storage que vous contrôlez, vous pouvez procéder comme suit:
- Créez un compte de service pouvant accéder à tous les bucket Cloud Storage que vous possédez.
- Générez un jeton d'accès OAuth 2.0 pour un compte de service :
- Appliquez une limite d'accès aux identifiants qui n'autorise que l'accès au bucket contenant les données de votre client.
Fonctionnement des limites d'accès aux identifiants
Pour réduire le champ d'application des autorisations, vous définissez une limite d'accès aux identifiants qui spécifie les ressources auxquelles l'identifiant éphémère peut accéder, ainsi que la limite supérieure des autorisations disponibles pour chaque ressource. Vous pouvez ensuite créer un identifiant éphémère, puis l'échanger contre un identifiant qui respecte la limite d'accès aux identifiants.
Si vous souhaitez octroyer aux comptes principaux un ensemble distinct d'autorisations pour chaque session, l'utilisation des limites d'accès aux identifiants peut s'avérer plus efficace que la création de nombreux comptes et l'octroi d'un ensemble différent de rôles à chaque compte de service.
Exemples de limites d'accès aux identifiants
Les sections suivantes présentent des exemples de limites d'accès aux identifiants pour les cas d'utilisation courants. Vous utilisez la limite d'accès aux identifiants lorsque vous échangez un jeton d'accès OAuth 2.0 avec un jeton aux champs d'application limités.
Limiter les autorisations pour un bucket
L'exemple suivant illustre une limite d'accès aux identifiants élémentaire. Elle s'applique au bucket Cloud Storage example-bucket
et définit la limite supérieure des autorisations incluses dans le rôle Lecteur d'objets Storage (roles/storage.objectViewer
) :
{
"accessBoundary": {
"accessBoundaryRules": [
{
"availablePermissions": [
"inRole:roles/storage.objectViewer"
],
"availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket"
}
]
}
}
Limiter les autorisations pour plusieurs buckets
L'exemple suivant illustre une limite d'accès aux identifiants qui inclut des règles pour plusieurs buckets :
- Le bucket Cloud Storage
example-bucket-1
: pour ce bucket, seules les autorisations du rôle "Lecteur des objets Storage" (roles/storage.objectViewer
) sont disponibles. - Le bucket Cloud Storage
example-bucket-2
: pour ce bucket, seules les autorisations du rôle "Créateur d'objets Storage" (roles/storage.objectCreator
) sont disponibles.
{
"accessBoundary": {
"accessBoundaryRules": [
{
"availablePermissions": [
"inRole:roles/storage.objectViewer"
],
"availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket-1"
},
{
"availablePermissions": [
"inRole:roles/storage.objectCreator"
],
"availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket-2"
}
]
}
}
Limiter les autorisations pour des objets spécifiques
Vous pouvez également utiliser les conditions IAM pour spécifier les objets Cloud Storage auxquels un compte principal peut accéder. Par exemple, vous pouvez ajouter une condition qui rend disponibles les autorisations pour les objets dont le nom commence par customer-a
:
{ "accessBoundary": { "accessBoundaryRules": [ { "availablePermissions": [ "inRole:roles/storage.objectViewer" ], "availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket", "availabilityCondition": { "expression" : "resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a')" } } ] } }
Limiter les autorisations lors de la création d'une liste d'objets
Lorsque vous répertoriez les objets dans un bucket Cloud Storage, vous appelez une méthode sur une ressource de bucket, et non sur une ressource d'objet. Par conséquent, si une condition est évaluée pour une requête de liste et que la condition fait référence au nom de ressource, ce nom identifie le bucket et non pas un objet dans le bucket. Par exemple, lorsque vous répertoriez des objets dans example-bucket
, le nom de la ressource est projects/_/buckets/example-bucket
.
Cette convention de dénomination peut entraîner un comportement inattendu lorsque vous répertoriez des objets.
Par exemple, supposons que vous souhaitiez instaurer une limite d'accès aux identifiants qui autorise l'accès en lecture aux objets de example-bucket
comportant le préfixe customer-a/invoices/
.
Vous pouvez essayer d'utiliser la condition suivante dans la limite d'accès aux identifiants :
Incomplete : condition qui vérifie uniquement le nom de la ressource
resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/')
Cette condition fonctionne pour la lecture d'objets, mais pas pour la création d'une liste des objets :
- Lorsqu'un compte principal tente de lire un objet dans
example-bucket
comportant le préfixecustomer-a/invoices/
, la condition renvoie la valeurtrue
. - Lorsqu'un compte principal essaie de répertorier des objets comportant ce préfixe, la condition renvoie la valeur
false
. La valeur deresource.name
, à savoirprojects/_/buckets/example-bucket
, ne commence pas parprojects/_/buckets/example-bucket/objects/customer-a/invoices/
.
Pour éviter ce type de problème à l'avenir, votre condition peut utiliser resource.name.startsWith()
et vérifier un attribut d'API nommé storage.googleapis.com/objectListPrefix
. Cet attribut contient la valeur du paramètre prefix
utilisé pour filtrer la liste des objets. Par conséquent, vous pouvez écrire une condition faisant référence à la valeur du paramètre prefix
.
L'exemple suivant montre comment utiliser l'attribut d'API dans une condition. Cela permet de lire et de répertorier les objets de example-bucket
comportant le préfixe customer-a/invoices/
:
Complete : condition qui vérifie le nom de la ressource et le préfixe
resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/') || api.getAttribute('storage.googleapis.com/objectListPrefix', '') .startsWith('customer-a/invoices/')
Vous pouvez désormais utiliser cette condition dans une limite d'accès aux identifiants :
{
"accessBoundary": {
"accessBoundaryRules": [
{
"availablePermissions": [
"inRole:roles/storage.objectViewer"
],
"availableResource": "//storage.googleapis.com/projects/_/buckets/example-bucket",
"availabilityCondition": {
"expression":
"resource.name.startsWith('projects/_/buckets/example-bucket/objects/customer-a/invoices/') || api.getAttribute('storage.googleapis.com/objectListPrefix', '').startsWith('customer-a/invoices/')"
}
}
]
}
}
Avant de commencer
Avant d'utiliser les limites d'accès aux identifiants, assurez-vous de remplir les conditions suivantes :
Vous devez réduire le champ d'application des autorisations pour Cloud Storage uniquement, et non pour les autres services Google Cloud.
Si vous devez réduire le champ d'application des autorisations associées à d'autres services Google Cloud, vous pouvez créer plusieurs comptes de service et attribuer un ensemble de rôles différent à chaque compte de service.
Vous pouvez utiliser les jetons d'accès OAuth 2.0 pour l'authentification. Les autres types d'identifiants éphémères ne sont pas compatibles avec les limites d'accès aux identifiants.
En outre, vous devez activer les API nécessaires :
-
Enable the IAM and Security Token Service APIs.
Créer un identifiant éphémère à champ d'application limité
Pour créer un jeton d'accès OAuth 2.0 avec des autorisations à champ d'application limité, procédez comme suit :
- Attribuez les rôles IAM appropriés à un utilisateur ou à un compte de service.
- Définissez une limite d'accès aux identifiants qui définit la limite supérieure des autorisations disponibles pour l'utilisateur ou le compte de service.
- Créez un jeton d'accès OAuth 2.0 pour l'utilisateur ou le compte de service.
- Échangez le jeton d'accès OAuth 2.0 contre un nouveau jeton respectant la limite d'accès aux identifiants.
Vous pouvez ensuite utiliser le nouveau jeton d'accès OAuth 2.0 à champ d'application limité pour authentifier les requêtes dans Cloud Storage.
Accorder des rôles IAM
Une limite d'accès aux identifiants définit la limite supérieure des autorisations disponibles pour une ressource. Cette limite peut retirer des autorisations à un compte principal, mais ne peut pas ajouter d'autorisations que le compte principal ne possède pas déjà.
Par conséquent, vous devez attribuer au compte principal des rôles qui fournissent les autorisations nécessaires dans un bucket Cloud Storage ou sur une ressource de niveau supérieur, comme le projet.
Supposons, par exemple, que vous ayez besoin de créer des identifiants éphémères à champ d'application limité, permettant à un compte de service de créer des objets dans un bucket :
- Vous devez au moins octroyer au compte de service un rôle comprenant l'autorisation
storage.objects.create
, par exemple le rôle Créateur d'objets Storage (roles/storage.objectCreator
). La limite d'accès aux identifiants doit également inclure cette autorisation. - Vous pouvez également attribuer un rôle comprenant davantage d'autorisations, tel que le rôle Administrateur d'objets Storage (
roles/storage.objectAdmin
). Le compte de service ne peut utiliser que les autorisations qui apparaissent à la fois dans le rôle attribué et dans la limite d'accès aux identifiants.
Pour en savoir plus sur les rôles prédéfinis pour Cloud Storage, consultez la page Rôles Cloud Storage.
Composants d'une limite d'accès aux identifiants
Une limite d'accès aux identifiants est un objet qui contient une liste de règles de limite d'accès. Chaque règle contient les informations suivantes :
- La ressource à laquelle s'applique la règle.
- La limite supérieure des autorisations disponibles pour cette ressource.
- Facultatif : une condition qui limite davantage les autorisations. Une condition inclut les éléments suivants :
- Une expression de condition qui renvoie
true
oufalse
. Si elle renvoietrue
, l'accès est autorisé. Sinon, l'accès est refusé. - Facultatif : un titre identifiant la condition.
- Facultatif : une description contenant des informations complémentaires sur la condition.
- Une expression de condition qui renvoie
Si vous appliquez une limite d'accès à un identifiant éphémère, celui-ci ne peut accéder qu'aux ressources spécifiées dans la limite d'accès aux identifiants. Aucune autorisation n'est disponible pour les autres ressources.
Une limite d'accès aux identifiants peut contenir jusqu'à 10 règles de limite d'accès. Vous ne pouvez appliquer qu'une seule limite d'accès par identifiant éphémère.
Lorsqu'elle est représentée sous la forme d'un objet JSON, une limite d'accès aux identifiants contient les champs suivants :
Champs | |
---|---|
accessBoundary |
Wrapper pour la limite d'accès aux identifiants. |
accessBoundary.accessBoundaryRules[] |
Liste des règles de limite d'accès à appliquer à un identifiant éphémère. |
accessBoundary.accessBoundaryRules[].availablePermissions[] |
Liste qui définit la limite supérieure des autorisations disponibles pour la ressource.
Chaque valeur est l'identifiant d'un rôle prédéfini ou d'un rôle personnalisé IAM, avec le préfixe |
accessBoundary.accessBoundaryRules[].availableResource |
Nom de ressource complet du bucket Cloud Storage auquel la règle s'applique. Utilisez le format " |
accessBoundary.accessBoundaryRules[].availabilityCondition |
Facultatif. Condition limitant la disponibilité des autorisations à des objets Cloud Storage spécifiques. Utilisez ce champ si vous souhaitez que les autorisations soient disponibles pour des objets spécifiques plutôt que pour tous les objets d'un bucket Cloud Storage. |
accessBoundary.accessBoundaryRules[].availabilityCondition.expression |
Expression de condition qui spécifie les objets Cloud Storage pour lesquels des autorisations sont disponibles. Pour savoir comment faire référence à des objets spécifiques dans une expression de condition, consultez Attribut |
accessBoundary.accessBoundaryRules[].availabilityCondition.title |
Facultatif. Chaîne courte qui identifie la finalité de la condition. |
accessBoundary.accessBoundaryRules[].availabilityCondition.description |
Facultatif. Informations concernant la finalité de la condition. |
Pour obtenir des exemples au format JSON, consultez la section Exemples de limites d'accès aux identifiants sur cette page.
Créer un jeton d'accès OAuth 2.0
Avant de créer un identifiant éphémère à champ d'application limité, vous devez créer un jeton d'accès OAuth 2.0 standard. Vous pouvez ensuite échanger l'identifiant standard contre un identifiant à champ d'application limité. Lorsque vous créez le jeton d'accès, utilisez le champ d'application OAuth 2.0 https://www.googleapis.com/auth/cloud-platform
.
Pour créer un jeton d'accès pour un compte de service, vous pouvez mettre en œuvre le flux OAuth 2.0 de serveur à serveur ou utiliser l'API Service Account Credentials pour générer un jeton d'accès OAuth 2.0.
Pour créer un jeton d'accès pour un utilisateur, consultez la page Obtenir des jetons d'accès OAuth 2.0. Vous pouvez également utiliser OAuth 2.0 Playground pour créer un jeton d'accès pour votre propre compte Google.
Échanger le jeton d'accès OAuth 2.0
Une fois le jeton d'accès OAuth 2.0 créé, vous pouvez l'échanger contre un nouveau jeton à champ d'application limité respectant la limite d'accès aux identifiants. Ce processus implique généralement un agent de service de jetons et un consommateur de jetons:
L'agent de service de jetons est chargé de définir les limites d'accès aux identifiants et d'échanger un jeton d'accès contre un jeton à champ d'application limité.
L'agent de service de jetons peut utiliser une bibliothèque d'authentification compatible pour échanger automatiquement des jetons d'accès ou appeler le service de jetons de sécurité pour échanger des jetons manuellement.
Le consommateur de jetons demande un jeton d'accès à champ d'application limité à l'agent de service de jetons, puis utilise ce jeton pour effectuer une autre action.
Le consommateur de jetons peut utiliser une bibliothèque d'authentification compatible pour actualiser automatiquement les jetons d'accès avant leur expiration. Il peut également actualiser les jetons manuellement, ou encore autoriser l'expiration des jetons sans les actualiser.
Échanger et actualiser automatiquement le jeton d'accès
Si vous créez l'agent de service de jetons et le consommateur de jetons dans l'un des langages suivants, vous pouvez utiliser la bibliothèque d'authentification de Google pour échanger et actualiser automatiquement les jetons :
Go
Pour Go, vous pouvez échanger et actualiser automatiquement des jetons avec la version v0.0.0-20210819190943-2bc19b11175f ou une version ultérieure du package golang.org/x/oauth2
.
Pour vérifier quelle version de ce package vous utilisez, exécutez la commande suivante dans le répertoire de votre application :
go list -m golang.org/x/oauth2
L'exemple suivant montre comment un agent de service de jetons peut générer des jetons à champ d'application limité :
L'exemple suivant montre comment un consommateur de jetons peut utiliser un gestionnaire d'actualisation pour obtenir et actualiser automatiquement les jetons à champ d'application limité :
Java
Pour Java, vous pouvez échanger et actualiser automatiquement des jetons avec la version 1.1.0 ou une version ultérieure de l'artefact com.google.auth:google-auth-library-oauth2-http
.
Pour vérifier quelle version de cet artefact vous utilisez, exécutez la commande Maven suivante dans le répertoire de votre application :
mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http
L'exemple suivant montre comment un agent de service de jetons peut générer des jetons à champ d'application limité :
L'exemple suivant montre comment un consommateur de jetons peut utiliser un gestionnaire d'actualisation pour obtenir et actualiser automatiquement les jetons à champ d'application limité :
Node.js
Pour Node.js, vous pouvez échanger et actualiser automatiquement des jetons avec la version 7.9.0 ou une version ultérieure du package google-auth-library
.
Pour vérifier quelle version de ce package vous utilisez, exécutez la commande suivante dans le répertoire de votre application :
npm list google-auth-library
L'exemple suivant montre comment un agent de service de jetons peut générer des jetons à champ d'application limité :
L'exemple suivant montre comment un consommateur de jetons peut fournir un gestionnaire d'actualisation qui obtient et actualise automatiquement les jetons à champ d'application limité :
Python
Pour Python, vous pouvez échanger et actualiser automatiquement des jetons avec la version 2.0.0 ou une version ultérieure du package google-auth
.
Pour vérifier quelle version de ce package vous utilisez, exécutez la commande suivante dans l'environnement où le package est installé :
pip show google-auth
L'exemple suivant montre comment un agent de service de jetons peut générer des jetons à champ d'application limité :
L'exemple suivant montre comment un consommateur de jetons peut fournir un gestionnaire d'actualisation qui obtient et actualise automatiquement les jetons à champ d'application limité :
Échanger et actualiser manuellement le jeton d'accès
Un agent de service de jetons peut utiliser l'API Security Token Service pour échanger un jeton d'accès contre un jeton d'accès à champ d'application limité. Il peut ensuite fournir le jeton à champ d'application limité à un consommateur de jetons.
Pour échanger le jeton d'accès, utilisez la méthode HTTP et l'URL suivantes :
POST https://sts.googleapis.com/v1/token
Définissez l'en-tête Content-Type
de la requête sur application/x-www-form-urlencoded
. Spécifiez les champs suivants dans le corps de la requête :
Champs | |
---|---|
grant_type |
Utilisez la valeur |
options |
Limite d'accès aux identifiants au format JSON, encodée avec le encodage-pourcent. |
requested_token_type |
Utilisez la valeur |
subject_token |
Jeton d'accès OAuth 2.0 que vous souhaitez échanger. |
subject_token_type |
Utilisez la valeur |
La réponse est un objet JSON qui contient les champs suivants :
Champs | |
---|---|
access_token |
Jeton d'accès OAuth 2.0 à champ d'application limité respectant la limite d'accès aux identifiants. |
expires_in |
: délai avant expiration du nouveau jeton d'accès à champ d'application limité, exprimé en secondes. Ce champ n'est présent que si le jeton d'accès d'origine représente un compte de service. Lorsque ce champ n'est pas présent, le délai avant expiration du nouveau jeton d'accès à champ d'application limité est le même que celui du jeton d'accès d'origine. |
issued_token_type |
Contient la valeur |
token_type |
Contient la valeur |
Par exemple, si une limite d'accès aux identifiants au format JSON est stockée dans le fichier ./access-boundary.json
, vous pouvez utiliser la commande curl
suivante pour échanger le jeton d'accès. Remplacez original-token
par le jeton d'accès d'origine :
curl -H "Content-Type:application/x-www-form-urlencoded" \ -X POST \ https://sts.googleapis.com/v1/token \ -d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token_type=urn:ietf:params:oauth:token-type:access_token&requested_token_type=urn:ietf:params:oauth:token-type:access_token&subject_token=original-token" \ --data-urlencode "options=$(cat ./access-boundary.json)"
La réponse est semblable à l'exemple suivant :
{
"access_token": "ya29.dr.AbCDeFg-123456...",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token",
"token_type": "Bearer",
"expires_in": 3600
}
Lorsqu'un consommateur de jetons demande un jeton à champ d'application limité, l'agent de service de jetons doit répondre avec le jeton à champ d'application limité et le nombre de secondes avant expiration. Pour actualiser le jeton à champ d'application limité, le consommateur peut demander un jeton à champ d'application limité à l'agent avant l'expiration du jeton existant.
Étape suivante
- Apprenez-en plus sur le contrôle des accès pour Cloud Storage.
- Créez un identifiant de compte de service éphémère.
- Créez un jeton d'accès OAuth 2.0 pour un compte de service à l'aide du flux OAuth 2.0 de serveur à serveur ou de l'API Service Account Credentials.
- Créez un jeton d'accès OAuth 2.0 pour un utilisateur.
- Consultez les autorisations de chaque rôle prédéfini.
- Apprenez-en plus sur les rôles personnalisés.