Ressourcenbasierten Zugriff konfigurieren

In diesem Abschnitt wird beschrieben, wie Sie den Zugriff auf bestimmte Ressourcen mithilfe von bedingten Rollenbindungen in Ihren IAM-Richtlinien (Identity and Access Management) verwalten. Mit Ressourcenattributen in einem Bedingungsausdruck können Sie einen untergeordneten Bereich der Rollenbindung anhand vom Ressourcennamen, Ressourcentyp und/oder Google Cloud-Dienst zuweisen.

Vorbereitung

  • Lesen Sie die Übersicht über IAM-Bedingungen, um sich mit den Grundlagen von bedingten IAM-Rollenbindungen vertraut zu machen.
  • Sehen Sie sich die Ressourcenattribute an, die in einem Bedingungsausdruck verwendet werden können.
  • Das Attribut "Ressourcenname" kann den Zugriff auf diese Google Cloud-Dienste steuern:
    • Cloud Spanner
    • Cloud Storage
    • Compute Engine
    • Identity-Aware Proxy
    • Cloud Key Management Service
    • Resource Manager (nur Ressourcentyp und Ressourcendienst)
    • Secret Manager

Zugriff auf eine Gruppe von Ressourcen anhand von Ressourcennamenspräfixen zuweisen

Mit einer bedingten Rollenbindung können Sie Mitgliedern Zugriff auf Ressourcen zuweisen, deren Ressourcennamen einem Präfix entsprechen, beispielsweise Compute Engine VM-Instanzen, deren Namen mit einem bestimmten String beginnen. Das Präfix für Ressourcennamen wird normalerweise zum Gruppieren von Ressourcen verwendet, die für bestimmte Funktionen vorgesehen sind oder bestimmte Attribute haben.

Betrachten Sie das folgende Beispiel: Das Softwareunternehmen Beispiel GmbH führt Arbeitslasten auf bestimmten VM-Instanzen aus, die möglicherweise mit vertraulichen Gesundheitsdaten arbeiten. Andere nicht vertrauliche Arbeitslasten müssen in demselben Projekt ausgeführt werden. Beispiel GmbH möchte sicherstellen, dass seine Entwickler eingeschränkten Zugriff auf VM-Instanzen haben, die mit vertraulichen Daten arbeiten. Damit sie dieses Ziel erreichen, werden datensensible VM-Instanzen mit dem Präfix sensitiveAccess und andere VM-Instanzen mit dem Präfix devAccess benannt. Anschließend wird mit bedingten Rollenbindungen sichergestellt, dass die Entwickler mit normalen devAccess-VM-Instanzen produktiv bleiben können, ohne ihnen Zugriff auf sensitiveAccess-VM-Instanzen zuzuweisen.

Sie können zwar den Zugriff auch nur mit dem Bedingungsattribut resource.name verwalten, aber die Attribute resource.type und resource.service sind ebenfalls gebräuchlich. Mit diesen zusätzlichen Attributen verringern Sie die Wahrscheinlichkeit, dass eine Bedingung den Zugriff auf verschiedene Ressourcentypen mit ähnlichen Namen beeinträchtigt. Im Beispiel in diesem Abschnitt wird der Zugriff mit den Attributen resource.name und resource.type gesteuert.

So weisen Sie Compute Engine-Laufwerken und -Instanzen in einem Projekt Zugriff anhand eines Namenspräfixes zu:

Console

  1. Rufen Sie in der Cloud Console die Seite IAM auf.

    Zur Seite „IAM“

  2. Suchen Sie in der Mitgliederliste nach dem gewünschten Mitglied und klicken Sie auf die Schaltfläche .

  3. Suchen Sie im Bereich Berechtigungen bearbeiten die gewünschte Rolle, für die Sie eine Bedingung konfigurieren möchten. Klicken Sie dann unter Bedingung auf Bedingung hinzufügen.

  4. Geben Sie im Bereich Bedingung bearbeiten einen Titel und eine optionale Beschreibung für die Bedingung ein.

  5. Sie können einen Bedingungsausdruck entweder mit dem Builder für IAM-Bedingungen oder dem Bedingungseditor hinzufügen. Der Builder für IAM-Bedingungen bietet eine interaktive Oberfläche, in der Sie die gewünschte Bedingung, den Operator und andere Details zum Ausdruck auswählen können. Der Bedingungseditor bietet eine textbasierte Oberfläche zur manuellen Eingabe eines Ausdrucks mit der CEL-Syntax.

    Builder für IAM-Bedingungen:

    1. Klicken Sie auf das Drop-down-Menü Hinzufügen und dann auf Gruppierte Bedingungen.
    2. Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Typ aus.
    3. Wählen Sie aus dem Drop-down-Menü Operator den Wert ist aus.
    4. Wählen Sie im Drop-Down-Menü Ressourcentyp die Option compute.googleapis.com/Disk aus.
    5. Klicken Sie direkt unter der Bedingung, die Sie gerade eingegeben haben, auf die erste Schaltfläche Hinzufügen, um dem Ausdruck eine weitere Klausel hinzuzufügen.
    6. Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Name aus.
    7. Wählen Sie im Drop-down-Menü Operator die Option Beginnt mit aus.
    8. Geben Sie im Feld Wert den Ressourcennamen im entsprechenden Format, beispielsweise projects/project-123/zones/us-central1-a/disks/devAccess für ein Laufwerk ein, dessen Name mit devAccess beginnt.
    9. Klicken Sie links neben jeder Bedingung auf Und, damit beide Klauseln wahr sein müssen.
    10. Klicken Sie direkt über der Schaltfläche Speichern auf die Schaltfläche Hinzufügen, um weitere gruppierte Bedingungen hinzuzufügen.
    11. Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Typ aus.
    12. Wählen Sie aus dem Drop-down-Menü Operator den Wert ist aus.
    13. Wählen Sie im Drop-Down-Menü Ressourcentyp die Option compute.googleapis.com/Instance aus.
    14. Klicken Sie direkt unter der Bedingung, die Sie gerade eingegeben haben, auf die erste Schaltfläche Hinzufügen, um dem Ausdruck eine weitere Klausel hinzuzufügen.
    15. Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Name aus.
    16. Wählen Sie im Drop-down-Menü Operator die Option Beginnt mit aus.
    17. Geben Sie im Feld Wert den Ressourcennamen im richtigen Format ein, beispielsweise projects/project-123/zones/us-central1-a/instances/devAccess für eine Instanz, deren Name mit devAccess beginnt.
    18. Klicken Sie links neben jeder Bedingung auf Und, damit beide Klauseln wahr sein müssen.
    19. Klicken Sie direkt über der Schaltfläche Speichern auf die Schaltfläche Hinzufügen, um die dritte Gruppe von Bedingungen hinzuzufügen.
    20. Damit diese Bedingung tatsächlich keine Auswirkungen auf andere Ressourcen hat, fügen Sie auch diese Klauseln hinzu: Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Typ aus.
    21. Wählen Sie aus dem Drop-down-Menü Operator ist nicht aus.
    22. Wählen Sie im Drop-Down-Menü Ressourcentyp die Option compute.googleapis.com/Disk aus.
    23. Klicken Sie direkt unter der Bedingung, die Sie gerade eingegeben haben, auf die erste Schaltfläche Hinzufügen, um dem Ausdruck eine weitere Klausel hinzuzufügen.
    24. Wählen Sie im Drop-down-Menü Bedingungstyp die Option Ressource > Typ aus.
    25. Wählen Sie aus dem Drop-down-Menü Operator ist nicht aus.
    26. Wählen Sie im Drop-Down-Menü Ressourcentyp die Option compute.googleapis.com/Instance aus.
    27. Klicken Sie links neben jeder Bedingung auf Und, damit beide Klauseln wahr sein müssen.
    28. Wenn Sie fertig sind, sollte der Builder für IAM-Bedingungen in etwa so aussehen:

    29. Klicken Sie auf Speichern, um die Bedingung anzuwenden.

    30. Sobald der Bereich Bedingung bearbeiten geschlossen wurde, klicken Sie im Bereich Berechtigungen bearbeiten noch einmal auf Speichern, um die IAM-Richtlinie zu aktualisieren.

    Bedingungseditor:

    1. Klicken Sie auf den Tab Bedingungseditor und geben Sie diesen Ausdruck ein:

      (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. Nachdem Sie den Ausdruck eingegeben haben, können Sie optional die CEL-Syntax per Lint validieren. Klicken Sie dazu oberhalb des Textfelds oben rechts auf Linter ausführen.

    3. Klicken Sie auf Speichern, um die Bedingung anzuwenden.

    4. Sobald der Bereich Bedingung bearbeiten geschlossen wurde, klicken Sie im Bereich Berechtigungen bearbeiten noch einmal auf Speichern, um die IAM-Richtlinie zu aktualisieren.

gcloud

IAM-Richtlinien werden mit dem Muster Read-Modify-Write festgelegt.

Rufen Sie mit dem Befehl gcloud projects get-iam-policy die aktuelle IAM-Richtlinie für das Projekt ab. Im folgenden Beispiel wird die JSON-Version der Richtlinie in einen Pfad auf dem Laufwerk heruntergeladen.

Befehl:

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

Das JSON-Format der IAM-Richtlinie wird heruntergeladen:

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

Fügen Sie den folgenden hervorgehobenen Bedingungsausdruck hinzu, um die Richtlinie mit einer Ressourcennamen-Präfixbedingung zu konfigurieren. Wenn Sie nicht Version 263.0.0 oder höher des gcloud-Tools verwenden, achten Sie darauf, dass Sie den Wert version auf 3 aktualisiert haben. Wenn Sie eine neuere Version des gcloud-Tools verwenden, wird der maximale Richtlinienwert automatisch für Sie festgelegt:

{
  "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
}

Legen Sie als Nächstes die neue Richtlinie mit dem Befehl gcloud projects set-iam-policy fest:

gcloud projects set-iam-policy project-id filepath

Die neue bedingte Rollenbindung weist devs@example.com-Berechtigungen so zu:

  • Alle Laufwerks- und Instanzberechtigungen werden nur zugewiesen, wenn der Ressourcenname mit devAccess beginnt

  • Alle anderen Berechtigungen in der Rolle Instanzadministrator werden für alle anderen Ressourcentypen zugewiesen

REST

Verwenden Sie das Muster read-modify-write, um Zugriff auf bestimmte Ressourcen zu gewähren.

Lesen Sie zuerst die IAM-Richtlinie für das Projekt:

Die Methode projects.getIamPolicy der Resource Manager API ruft die IAM-Richtlinie eines Projekts ab.

Ersetzen Sie diese Werte in den folgenden Anweisungen:

  • project-id: Ihre Google Cloud-Projekt-ID.
  • policy-version: Die Richtlinienversion, die zurückgegeben werden soll. Anfragen sollten die neueste Richtlinienversion angeben. Diese ist Richtlinienversion 3. Weitere Informationen finden Sie unter Richtlinienversion beim Abrufen einer Richtlinie festlegen.

HTTP-Methode und URL:

POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

JSON-Text anfordern:

{
  "options": {
    "requestedPolicyVersion": policy-version
  }
}

Wenn Sie die Anfrage senden möchten, maximieren Sie eine der folgenden Optionen:

Sie sollten in etwa folgende JSON-Antwort erhalten:

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

Ändern Sie anschließend die Richtlinie, um den Zugriff auf bestimmte Ressourcen zu ermöglichen. Setzen Sie dabei das Feld version auf den Wert 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')"
      }
    }
  ]
}

Schreiben Sie anschließend die aktualisierte Richtlinie:

Die Methode projects.setIamPolicy der Resource Manager API legt die Richtlinie in der Anfrage als neue IAM-Richtlinie des Projekts fest.

Ersetzen Sie diese Werte in den folgenden Anweisungen:

  • project-id: Ihre Google Cloud-Projekt-ID.

HTTP-Methode und URL:

POST https://cloudresourcemanager.googleapis.com/v1/projects/project-id:setIamPolicy

JSON-Text anfordern:

{
  "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')"
        }
      }
    ]
  }
}

Wenn Sie die Anfrage senden möchten, maximieren Sie eine der folgenden Optionen:

Die Antwort enthält die aktualisierte Richtlinie.


Werte aus Ressourcennamen extrahieren

Die vorherigen Beispiele zeigen boolesche Vergleiche zwischen dem Ressourcennamen oder dem Anfang des Ressourcennamens und einem anderen Wert. In einigen Fällen müssen Sie jedoch einen Wert mit einem bestimmten Teil des Ressourcennamens vergleichen, der nicht am Anfang des Namens steht.

Sie können die extract()-Funktion verwenden und eine Extraktionsvorlage angeben, um den relevanten Teil des Ressourcennamens als String zu extrahieren. Bei Bedarf können Sie den extrahierten String in einen anderen Typ konvertieren, beispielsweise in einen Zeitstempel. Nachdem Sie einen Wert aus dem Ressourcennamen extrahiert haben, können Sie diesen mit anderen Werten vergleichen.

Die folgenden Beispiele zeigen Bedingungsausdrücke, die die Funktion extract() verwenden. Weitere Informationen zur Funktion extract() finden Sie in der Referenz zu Attributen für IAM Conditions.

Beispiel: Übereinstimmende Bestellungen der letzten 30 Tage

Angenommen, Sie speichern Auftragsinformationen in mehreren Cloud Storage-Buckets und die Objekte in jedem Bucket sind nach Datum organisiert. Ein typischer Objektname könnte in etwa so aussehen:

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

Sie möchten einen beliebigen Auftrag der letzten 30 Tage abgleichen. Die folgende Bedingung entspricht diesen Bestellungen. Sie verwendet die Funktionen duration() und date(), um 30 Tage (2.592.000 Sekunden) von der Anfragezeit abzuziehen und diesen Zeitstempel mit dem Bestelldatum zu vergleichen:

request.time - duration('2592000s') < date(resource.name.extract('/order_date={date_str}/'))

Weitere Informationen zu den Funktionen date() und duration() finden Sie in der Referenz zu Datums- und Uhrzeitattributen.

Beispiel: Übereinstimmende Compute Engine-VMs an einem beliebigen Standort

Angenommen, Sie müssen alle Compute Engine-VMs an jedem Speicherort abgleichen, dessen Name mit dev- beginnt. Der Ressourcenname für eine VM hat ein ähnliches Format wie projects/project-id/zones/zone-id/instances/instance-name. Die folgende Bedingung wird als true ausgewertet, wenn der Instanzname mit dem String dev- beginnt:

resource.name.extract('/instances/{name}/').startsWith('dev-')

Der Text in geschweiften Klammern gibt den Teil des Ressourcennamens an, der zum Vergleich extrahiert wird. In diesem Beispiel extrahiert die Extraktionsvorlage alle Zeichen zwischen dem ersten Vorkommen des Strings /instances/ und dem nächsten Vorkommen des Strings /.

Wichtige Nutzungshinweise für ressourcenbasierte Bedingungen

Beim Hinzufügen einer ressourcenbasierten Bedingung ist es wichtig zu berücksichtigen, wie sich die Bedingung auf die Berechtigungen des Mitglieds auswirkt.

Benutzerdefinierte Rollen

Betrachten Sie das folgende Beispiel mit benutzerdefinierten Rollen. Ein Administrator möchte eine benutzerdefinierte Rolle erstellen, die Zugriff zum Erstellen von VM-Instanzen gewährt. Der Nutzer kann jedoch nur VM-Instanzen in einem Projekt mit einem Ressourcennamen, der mit dem Namenspräfix staging beginnt, unter Verwendung der Laufwerke mit dem gleichen Namenspräfix erstellen.

Achten Sie daher darauf, dass die zugewiesene Rolle die erforderlichen Berechtigungen zum Erstellen einer VM-Instanz enthält, d. h. Berechtigungen für Laufwerks- und Instanzressourcentypen. Prüfen Sie dann, ob der Bedingungsausdruck den Ressourcennamen sowohl für Laufwerke als auch für Instanzen überprüft. Über diese beiden Typen hinaus werden keine anderen Berechtigungen in der Rolle gewährt.

Der folgende Bedingungsausdruck führt zu unerwartetem Verhalten. Berechtigungen für den Betrieb auf Compute Engine-VMs werden blockiert:

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

Der folgende Bedingungsausdruck enthält sowohl Laufwerke als auch Instanzen und verwaltet den Zugriff basierend auf dem Ressourcennamen für diese beiden Typen:

(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'))

Der folgende Bedingungsausdruck umfasst sowohl Laufwerke als auch Instanzen und verwaltet den Zugriff basierend auf dem Ressourcennamen für diese beiden Typen. Bei allen anderen Ressourcentypen gewährt der Bedingungsausdruck die Rolle unabhängig vom Ressourcennamen:

(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')

Nur für übergeordnete Ressourcen geltende Berechtigungen

In der Google Cloud-Ressourcenhierarchie dienen einige der Berechtigungen in einer Rolle, die eine untergeordnete Ressource betreffen, dazu, nur auf der übergeordneten Ebene erzwungen zu werden. Damit Nutzer beispielsweise kryptografische Schlüssel für Cloud KMS auflisten können, muss ihnen die Berechtigung cloudkms.cryptokeys.list für den Schlüsselbund gewährt werden, der die kryptografischen Schlüssel enthält, nicht für die Schlüssel selbst. Solche Berechtigungen werden als Berechtigungen für übergeordnete Ressourcen bezeichnet und gelten nur für list-Vorgänge.

Der Bedingungsausdruck muss die Attribute resource.service und resource.type entsprechend dem übergeordneten Ressourcentyp der Zielressourcen festlegen, um bei der Verwendung von Bedingungen den Zugriff auf *.*.list-Berechtigungen ordnungsgemäß zu gewähren.

Betrachten Sie hierzu folgende Beispiele. Im obigen Compute Engine-Beispiel verhindert der folgende Ausdruck den Zugriff auf compute.disks.list- und compute.instances.list-Berechtigungen, da die Ressource, für die diese Berechtigungen aktiviert sind, einen resource.type-Attributwert von cloudresourcemanager.googleapis.com/Project haben.

(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'))

Es ist üblich, dass diese list-Berechtigungen gemeinsam mit anderen Berechtigungen für reguläre Vorgänge auf der Ressource gewährt werden. In diesem Fall können Sie entweder den Gültigkeitsbereich nur für den Typ cloudresourcemanager.googleapis.com/Project erweitern oder den Umfang auf alle anderen Berechtigungen erweitern, die nicht vom Typ "Instanz" oder "Laufwerk" sind.

(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'

oder

(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')