Configurare l'accesso basato sulle risorse

Questo argomento descrive come gestire l'accesso a risorse specifiche utilizzando le associazioni di ruoli condizionali nei criteri di autorizzazione. Utilizzando gli attributi della risorsa in un'espressione della condizione, puoi concedere un ambito secondario dell'associazione dei ruoli in base al nome della risorsa, al tipo di risorsa e/o al servizio Google Cloud.

Prima di iniziare

  • Leggi la panoramica delle condizioni di Identity and Access Management (IAM) per comprendere i concetti di base delle associazioni di ruoli condizionali IAM.
  • Rivedi gli attributi della risorsa che possono essere utilizzati in un'espressione di condizione.
  • L'attributo del nome della risorsa può controllare l'accesso ai seguenti servizi Google Cloud:
    • Apigee X
    • Autorizzazione binaria
    • Cloud Bigtable
    • Cloud Key Management Service
    • Cloud Logging
    • Cloud Spanner
    • Cloud SQL
    • Cloud Storage
    • Compute Engine
    • Pub/Sub Lite
    • Secret Manager

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per gestire le associazioni di ruoli condizionali, chiedi all'amministratore di concederti i seguenti ruoli IAM:

  • Per gestire l'accesso ai progetti: Amministratore IAM progetto (roles/resourcemanager.projectIamAdmin) nel progetto
  • Per gestire l'accesso alle cartelle: Amministratore cartelle (roles/resourcemanager.folderAdmin) nella cartella
  • Per gestire l'accesso a progetti, cartelle e organizzazioni: Amministratore organizzazione (roles/resourcemanager.organizationAdmin) nell'organizzazione
  • Per gestire l'accesso a quasi tutte le risorse Google Cloud: Amministratore sicurezza (roles/iam.securityAdmin) nel progetto, nella cartella o nell'organizzazione di cui vuoi gestire l'accesso

Per ulteriori informazioni sulla concessione dei ruoli, consulta Gestire l'accesso.

Questi ruoli predefiniti contengono le autorizzazioni necessarie per gestire le associazioni di ruoli condizionali. Per visualizzare le autorizzazioni esatte richieste, espandi la sezione Autorizzazioni richieste:

Autorizzazioni obbligatorie

  • Per gestire l'accesso ai progetti:
    • resourcemanager.projects.getIamPolicy nel progetto
    • resourcemanager.projects.setIamPolicy nel progetto
  • Per gestire l'accesso alle cartelle:
    • resourcemanager.folders.getIamPolicy nella cartella
    • resourcemanager.folders.setIamPolicy nella cartella
  • Per gestire l'accesso alle organizzazioni:
    • resourcemanager.organizations.getIamPolicy nell'organizzazione
    • resourcemanager.organizations.setIamPolicy nell'organizzazione

Potresti anche essere in grado di ottenere queste autorizzazioni con ruoli personalizzati o altri ruoli predefiniti.

Concedi l'accesso a un gruppo di risorse in base ai prefissi dei nomi delle risorse

Un'associazione di ruolo condizionale può essere utilizzata per concedere l'accesso alle entità per le risorse i cui nomi di risorsa corrispondono a un prefisso, come le istanze di macchine virtuali (VM) di Compute Engine i cui nomi iniziano con una determinata stringa. Il prefisso del nome della risorsa viene generalmente utilizzato per raggruppare le risorse destinate a determinate funzionalità o con determinate proprietà.

Considera l'esempio seguente: la società di software ExampleCo esegue carichi di lavoro su determinate istanze VM che potrebbero funzionare su dati sanitari sensibili. Altri carichi di lavoro non sensibili devono essere eseguiti nello stesso progetto e ExampleCo vuole assicurarsi che i suoi sviluppatori abbiano accesso limitato alle istanze VM che operano sui dati sensibili. Per raggiungere questo obiettivo, le istanze VM sensibili ai dati hanno un prefisso sensitiveAccess, mentre le altre istanze VM hanno un prefisso devAccess. Quindi, le associazioni di ruoli condizionali vengono utilizzate per garantire che gli sviluppatori possano rimanere produttivi con le normali istanze VM devAccess, ma senza concedere loro l'accesso alle istanze VM sensitiveAccess.

Anche se puoi utilizzare l'attributo condizione resource.name da solo per gestire l'accesso, è comune utilizzare anche gli attributi resource.type e resource.service. Se utilizzi questi attributi aggiuntivi, riduci le probabilità che una condizione influisca sull'accesso a diversi tipi di risorse con nomi simili. L'esempio in questa sezione controlla l'accesso tramite gli attributi resource.name e resource.type.

Per concedere l'accesso in base a un prefisso nome ai dischi e alle istanze di Compute Engine in un progetto:

Console

  1. In Cloud Console, vai alla pagina IAM.

    Vai alla pagina IAM

  2. Nell'elenco delle entità, individua l'entità desiderata e fai clic sul pulsante .

  3. Dal riquadro Modifica autorizzazioni, individua il ruolo da configurare per una condizione. Nella sezione Condizione, fai clic su Aggiungi condizione.

  4. Nel riquadro Modifica condizione, inserisci un titolo e una descrizione facoltativa per la condizione.

  5. Puoi aggiungere un'espressione della condizione utilizzando il Generatore di condizioni o l'Editor condizioni. Il generatore di condizioni fornisce un'interfaccia interattiva per selezionare il tipo di condizione desiderato, l'operatore e altri dettagli applicabili sull'espressione. L'editor condizioni fornisce un'interfaccia di testo per inserire manualmente un'espressione utilizzando la sintassi CEL.

    Generatore di condizioni:

    1. Fai clic sul menu a discesa Aggiungi e su Condizioni raggruppate.
    2. Dal menu a discesa Tipo di condizione, seleziona Risorsa > Tipo.
    3. Dal menu a discesa Operatore, seleziona è.
    4. Dal menu a discesa Tipo di risorsa, seleziona compute.googleapis.com/Disk.
    5. Fai clic sul primo pulsante Aggiungi immediatamente sotto la condizione che hai appena inserito per aggiungere un'altra clausola all'espressione.
    6. Dal menu a discesa Tipo di condizione, seleziona Risorsa > nome.
    7. Dal menu a discesa Operatore, seleziona Inizia con.
    8. Nel campo Valore, inserisci il nome della risorsa nel formato appropriato, ad esempio projects/project-123/zones/us-central1-a/disks/devAccess per un disco il cui nome inizia con devAccess.
    9. A sinistra di ciascun tipo di condizione, fai clic su E per assicurarti che entrambe le clausole devono essere true.
    10. Fai clic sul pulsante Aggiungi sopra il pulsante Salva per aggiungere un altro insieme di condizioni raggruppate.
    11. Dal menu a discesa Tipo di condizione, seleziona Risorsa > Tipo.
    12. Dal menu a discesa Operatore, seleziona è.
    13. Dal menu a discesa Tipo di risorsa, seleziona compute.googleapis.com/Instance.
    14. Fai clic sul primo pulsante Aggiungi immediatamente sotto la condizione che hai appena inserito, aggiungi un'altra clausola all'espressione.
    15. Dal menu a discesa Tipo di condizione, seleziona Risorsa > nome.
    16. Dal menu a discesa Operatore, seleziona Inizia con.
    17. Nel campo Valore, inserisci il nome della risorsa nel formato appropriato, ad esempio projects/project-123/zones/us-central1-a/instances/devAccess per un'istanza il cui nome inizia con devAccess.
    18. A sinistra di ciascun tipo di condizione, fai clic su E per assicurarti che entrambe le clausole devono essere true.
    19. Fai clic sul pulsante Add (Aggiungi) direttamente sopra il pulsante Save (Salva) per aggiungere il terzo insieme di condizioni raggruppate.
    20. Per assicurarti che questa condizione non influisca anche su altre risorse, aggiungi anche le seguenti clausole: dal menu a discesa Tipo di condizione, seleziona Risorsa e tipo.
    21. Dal menu a discesa Operatore, seleziona non è.
    22. Dal menu a discesa Tipo di risorsa, seleziona compute.googleapis.com/Disk.
    23. Fai clic sul primo pulsante Aggiungi immediatamente sotto la condizione che hai appena inserito, aggiungi un'altra clausola all'espressione.
    24. Dal menu a discesa Tipo di condizione, seleziona Risorsa > Tipo.
    25. Dal menu a discesa Operatore, seleziona non è.
    26. Dal menu a discesa Tipo di risorsa, seleziona compute.googleapis.com/Instance.
    27. A sinistra di ciascun tipo di condizione, fai clic su E per assicurarti che entrambe le clausole devono essere true.
    28. Al termine, il generatore di condizioni dovrebbe essere simile al seguente:

    29. Fai clic su Salva per applicare la condizione.

    30. Una volta chiuso il riquadro Modifica condizione, fai clic di nuovo su Salva nel riquadro Modifica autorizzazioni per aggiornare il criterio di autorizzazione.

    Editor condizioni:

    1. Fai clic sulla scheda Condition Editor e inserisci la seguente espressione:

      (resource.type == "compute.googleapis.com/Disk" &&
      resource.name.startsWith("projects/project-123/regions/us-central1/disks/devAccess")) ||
      (resource.type == "compute.googleapis.com/Instance" &&
      resource.name.startsWith("projects/project-123/zones/us-central1-a/instances/devAccess")) ||
      (resource.type != "compute.googleapis.com/Disk" &&
      resource.type != "compute.googleapis.com/Instance")
    2. Dopo aver inserito l'espressione, puoi scegliere di inclinare la sintassi CEL facendo clic su Esegui linter sopra la casella di testo in alto a destra.

    3. Fai clic su Salva per applicare la condizione.

    4. Una volta chiuso il riquadro Modifica condizione, fai clic di nuovo su Salva nel riquadro Modifica autorizzazioni per aggiornare il criterio di autorizzazione.

gcloud

I criteri di autorizzazione vengono impostati utilizzando il pattern read-Modify-write.

Esegui il comando gcloud projects get-iam-policy per ottenere l'attuale criterio di autorizzazione per il progetto. Nell'esempio seguente, la versione JSON del criterio di autorizzazione viene scaricata su un percorso su disco.

Comando:

gcloud projects get-iam-policy project-id --format=json > filepath

Viene scaricato il formato JSON del criterio di autorizzazione:

{
  "bindings": [
    {
      "members": [
        "user:project-owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "group:devs@example.com"
      ],
      "role": "roles/compute.instanceAdmin"
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 1
}

Per configurare il criterio di autorizzazione con una condizione Prefisso nome risorsa, aggiungi la seguente espressione della condizione evidenziata. L'interfaccia a riga di comando gcloud aggiorna automaticamente la versione:

{
  "bindings": [
    {
      "members": [
        "user:project-owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "group:devs@example.com"
      ],
      "role": "roles/compute.instanceAdmin",
      "condition": {
          "title": "Dev_access_only",
          "description": "Only access to devAccess* VMs",
          "expression":
            "(resource.type == 'compute.googleapis.com/Disk' &&
            resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
            (resource.type == 'compute.googleapis.com/Instance' &&
            resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess')) ||
            (resource.type != 'compute.googleapis.com/Instance' &&
            resource.type != 'compute.googleapis.com/Disk')"
      }
    }
  ],
  "etag": "BwWKmjvelug=",
  "version": 3
}

Quindi, imposta il nuovo criterio di autorizzazione eseguendo il comando gcloud projects set-iam-policy:

gcloud projects set-iam-policy project-id filepath

La nuova associazione di ruoli condizionale concederà le autorizzazioni devs@example.com nel seguente modo:

  • Tutte le autorizzazioni disco e istanza sono concesse solo se il nome risorsa inizia con devAccess

  • Tutte le altre autorizzazioni nel ruolo Amministratore di istanze vengono concesse per tutti gli altri tipi di risorse

REST

Utilizza il pattern read-Modify-write per consentire l'accesso a risorse specifiche.

Per prima cosa, leggi il criterio di autorizzazione per il progetto:

Il metodo projects.getIamPolicy dell'API Resource Manager riceve un criterio di autorizzazione del progetto.

Prima di utilizzare uno qualsiasi dei dati della richiesta, effettua le seguenti sostituzioni:

  • PROJECT_ID: ID progetto Google Cloud. Gli ID progetto sono stringhe alfanumeriche, come my-project.
  • POLICY_VERSION: la versione del criterio da restituire. Le richieste devono specificare la versione più recente del criterio, ossia la versione 3. Per informazioni dettagliate, vedi Specificare la versione di un criterio quando si riceve un criterio.

Metodo HTTP e URL:

POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:getIamPolicy

Corpo JSON richiesta:

{
  "options": {
    "requestedPolicyVersion": POLICY_VERSION
  }
}

Per inviare la richiesta, espandi una delle seguenti opzioni:

Dovresti ricevere una risposta JSON simile alla seguente:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/owner",
      "members": [
        "user:project-owner@example.com"
      ]
    },
    {
      "members": [
        "group:devs@example.com"
      ],
      "role": "roles/compute.instanceAdmin"
    }
  ]
}

Adesso modifica il criterio di autorizzazione in modo da consentire l'accesso a risorse specifiche. Assicurati di modificare il campo version impostandolo sul valore 3:

{
  "version": 3,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/owner",
      "members": [
        "user:project-owner@example.com"
      ]
    },
    {
      "role": "roles/compute.instanceAdmin",
      "members": [
        "group:devs@example.com"
      ],
      "condition": {
          "title": "Dev_access_only",
          "description": "Only access to devAccess* VMs",
          "expression":
            "(resource.type == 'compute.googleapis.com/Disk' &&
            resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
            (resource.type == 'compute.googleapis.com/Instance' &&
            resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess')) ||
            (resource.type != 'compute.googleapis.com/Instance' &&
            resource.type != 'compute.googleapis.com/Disk')"
      }
    }
  ]
}

Infine, scrivi il criterio di autorizzazione aggiornato:

Il metodo projects.setIamPolicy dell'API Resource Manager imposta il criterio di autorizzazione nella richiesta come nuovo criterio di autorizzazione del progetto.

Prima di utilizzare uno qualsiasi dei dati della richiesta, effettua le seguenti sostituzioni:

  • PROJECT_ID: ID progetto Google Cloud. Gli ID progetto sono stringhe alfanumeriche, come my-project.

Metodo HTTP e URL:

POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy

Corpo JSON richiesta:

{
  "policy": {
    "version": 3,
    "etag": "BwWKmjvelug=",
    "bindings": [
      {
        "role": "roles/owner",
        "members": [
          "user:project-owner@example.com"
        ]
      },
      {
        "role": "roles/compute.instanceAdmin",
        "members": [
          "group:devs@example.com"
        ],
        "condition": {
          "title": "Dev_access_only",
          "description": "Only access to devAccess* VMs",
          "expression":
            "(resource.type == 'compute.googleapis.com/Disk' &&
            resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
            (resource.type == 'compute.googleapis.com/Instance' &&
            resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess')) ||
            (resource.type != 'compute.googleapis.com/Instance' &&
            resource.type != 'compute.googleapis.com/Disk')"
        }
      }
    ]
  }
}

Per inviare la richiesta, espandi una delle seguenti opzioni:

La risposta contiene il criterio di autorizzazione aggiornato.


Estrai valori dai nomi delle risorse

Gli esempi precedenti mostrano confronti booleani tra il nome della risorsa o l'inizio del nome e un altro valore. In alcuni casi, tuttavia, potrebbe essere necessario confrontare un valore con una parte specifica del nome della risorsa, che non è all'inizio.

Puoi utilizzare la funzione extract() e specificare un modello di estrazione per estrarre la parte pertinente del nome della risorsa come stringa. Se necessario, puoi convertire la stringa estratta in un altro tipo, ad esempio un timestamp. Dopo aver estratto un valore dal nome della risorsa, puoi confrontarlo con altri valori.

I seguenti esempi mostrano espressioni di condizioni che utilizzano la funzione extract(). Per maggiori dettagli sulla funzione extract(), consulta il riferimento per l'attributo Condizioni IAM.

Esempio: corrispondenza degli ordini degli ultimi 30 giorni

Supponi di archiviare le informazioni sugli ordini in più bucket Cloud Storage e che gli oggetti in ciascun bucket sono organizzati per data. Il nome di un oggetto tipico potrebbe essere simile a questo esempio:

projects/_/buckets/acme-orders-aaa/objects/data_lake/orders/order_date=2019-11-03/aef87g87ae0876

Vuoi consentire a un'entità di accedere a qualsiasi ordine degli ultimi 30 giorni. La seguente condizione corrisponde agli oggetti Cloud Storage di questi ordini. Utilizza le funzioni duration() e date() per sottrarre 30 giorni (2.592.000 secondi) dall'ora della richiesta, quindi confronta il timestamp con la data dell'ordine:

resource.type == 'storage.googleapis.com/Object' &&
  request.time - duration('2592000s') < date(resource.name.extract('/order_date={date_str}/'))

Per maggiori dettagli sulle funzioni date() e duration(), consulta il riferimento attributo data/ora.

Esempio: crea una corrispondenza con le VM di Compute Engine in qualsiasi località

Supponi di voler concedere un ruolo a livello di progetto a un'entità per qualsiasi VM di Compute Engine il cui nome inizia con dev-, indipendentemente dalla posizione della VM. Vuoi anche che l'entità possa utilizzare quel ruolo per tutti gli altri tipi di risorse.

Il nome della risorsa per una VM utilizza un formato simile a projects/project-id/zones/zone-id/instances/instance-name. La condizione indicata di seguito restituisce true per le VM con un nome istanza che inizia con la stringa dev- e per tutti i tipi di risorse diversi dalle VM:

resource.type != 'compute.googleapis.com/Instance' ||
  resource.name.extract('/instances/{name}').startsWith('dev-')

Il testo tra parentesi graffe identifica la parte del nome della risorsa che viene estratta per il confronto. In questo esempio, il modello di estrazione estrae qualsiasi carattere dopo la prima occorrenza della stringa /instances/.

Considerazioni importanti sull'utilizzo per le condizioni basate sulle risorse

Quando aggiungi una condizione basata su risorse, è importante considerare in che modo la condizione influisce sulle autorizzazioni dell'entità.

Ruoli personalizzati

Esamina il seguente esempio, che prevede i ruoli personalizzati. Un amministratore vuole creare un ruolo personalizzato che conceda l'accesso per creare istanze VM, ma consente solo all'utente di creare istanze VM in un progetto con un nome risorsa che inizia con il prefisso nome staging, utilizzando i dischi con lo stesso prefisso.

Per raggiungere questo obiettivo, assicurati che il ruolo concesso contenga le autorizzazioni necessarie per creare un'istanza VM, che prevede autorizzazioni per i dischi e per i tipi di risorse dell'istanza. Quindi, assicurati che l'espressione della condizione controlli il nome della risorsa per entrambi i dischi e le istanze. Oltre a questi due tipi, non sono concesse altre autorizzazioni nel ruolo.

La seguente espressione della condizione comporterà comportamenti imprevisti. Le autorizzazioni per l'esecuzione sulle VM di Compute Engine sono bloccate:

resource.type == 'compute.googleapis.com/Disk' &&
 resource.name.startsWith('projects/project-123/regions/us-central1/disks/staging')

La seguente espressione della condizione include sia i dischi che le istanze e gestirà l'accesso in base al nome della risorsa per questi due tipi:

(resource.type == 'compute.googleapis.com/Disk' &&
  resource.name.startsWith('projects/project-123/regions/us-central1/disks/staging')) ||
 (resource.type == 'compute.googleapis.com/Instance' &&
  resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/staging'))

La seguente espressione della condizione include sia i dischi che le istanze e gestirà l'accesso in base al nome della risorsa per questi due tipi. Per qualsiasi altro tipo di risorsa, l'espressione della condizione concede il ruolo indipendentemente dal nome della risorsa:

(resource.type == 'compute.googleapis.com/Disk' &&
  resource.name.startsWith('projects/project-123/regions/us-central1/disks/staging')) ||
 (resource.type == 'compute.googleapis.com/Instance' &&
  resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/staging')) ||
 (resource.type != 'compute.googleapis.com/Disk' &&
  resource.type != 'compute.googleapis.com/Instance')

Autorizzazioni riservate ai genitori

Nella gerarchia delle risorse di Google Cloud, alcune delle autorizzazioni di un ruolo che interessano una risorsa secondaria sono destinate ad essere applicate solo al livello padre. Ad esempio, per elencare le chiavi di crittografia per Cloud KMS, all'utente deve essere concessa l'autorizzazione cloudkms.cryptokeys.list per il keyring che contiene le chiavi di crittografia, non le chiavi stesse. Questi tipi di autorizzazioni sono chiamate autorizzazioni solo per i genitori e si applicano solo alle operazioni list.

Per concedere correttamente l'accesso alle autorizzazioni *.*.list quando utilizzi delle condizioni, l'espressione della condizione deve impostare gli attributi resource.service e resource.type in base al tipo di risorsa principale delle risorse di destinazione da elencare.

Esamina i seguenti esempi. Utilizzando l'esempio di Compute Engine riportato in precedenza, la seguente espressione impedisce l'accesso alle autorizzazioni compute.disks.list e compute.instances.list, poiché la risorsa su cui sono controllate queste autorizzazioni ha un valore attributo resource.type pari a cloudresourcemanager.googleapis.com/Project.

(resource.type == 'compute.googleapis.com/Disk' &&
  resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
 (resource.type == 'compute.googleapis.com/Instance' &&
  resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess'))

È normale che queste autorizzazioni list vengano concesse insieme ad altre autorizzazioni per le operazioni regolari sulla risorsa. Per aumentare l'ambito della concessione in questo caso, puoi estendere l'ambito solo per il tipo cloudresourcemanager.googleapis.com/Project o estenderlo a tutte le altre autorizzazioni che non siano di tipo istanza o disco.

(resource.type == 'compute.googleapis.com/Disk' &&
  resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
 (resource.type == 'compute.googleapis.com/Instance' &&
  resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess')) ||
 resource.type == 'cloudresourcemanager.googleapis.com/Project'

o

(resource.type == 'compute.googleapis.com/Disk' &&
  resource.name.startsWith('projects/project-123/regions/us-central1/disks/devAccess')) ||
 (resource.type == 'compute.googleapis.com/Instance' &&
  resource.name.startsWith('projects/project-123/zones/us-central1-a/instances/devAccess')) ||
 (resource.type != 'compute.googleapis.com/Disk' &&
  resource.type != 'compute.googleapis.com/Instance')