Membuat kredensial jangka pendek untuk beberapa akun layanan

Halaman ini berisi penjelasan mengenai cara membuat kredensial jangka pendek untuk akun layanan berdasarkan rantai delegasi akun layanan. Pendekatan ini dapat digunakan saat Anda perlu melakukan serangkaian panggilan pembuatan token untuk memperoleh token dengan izin yang diperlukan guna menyelesaikan tugas.

Setelah mendapatkan kredensial jangka pendek, Anda dapat menggunakannya untuk meniru identitas akun layanan.

Jika Anda membuat token dengan izin yang diperlukan dalam satu panggilan pembuatan token, Anda harus membuat kredensial jangka pendek untuk akun layanan tersebut secara langsung.

Mengenai pembuatan kredensial jangka pendek

Anda dapat menggunakan kredensial jangka pendek untuk mengautentikasi panggilan ke Google API, API pihak ketiga, atau aplikasi yang memerlukan token ID, tergantung pada jenis token yang dibuat. Kredensial jangka pendek memiliki masa aktif terbatas dengan durasi beberapa jam atau kurang, serta tidak dapat otomatis diperbarui. Kredensial akun layanan jangka pendek berguna untuk skenario saat Anda perlu memberikan akses terbatas ke resource pada akun layanan terpercaya. Kredensial tersebut juga memiliki risiko minimal daripada kredensial jangka panjang, seperti kunci akun layanan.

Anda dapat membuat jenis kredensial jangka pendek berikut untuk akun layanan:

  • Token akses OAuth 2.0

    Token akses dapat digunakan untuk autentikasi oleh sebagian besar Google API. Saat membuat token akses untuk akun layanan, token tersebut akan muncul tanpa token refresh. Artinya, saat masa aktif token akses berakhir, Anda harus mengulangi proses pembuatan token untuk membuat token baru.

    Untuk informasi selengkapnya, lihat Token akses.

  • Token ID OpenID Connect (OIDC)

    Token ID mengikuti spesifikasi OpenID Connect (OIDC). Token ID dapat digunakan oleh sejumlah layanan dan aplikasi.

    Untuk informasi selengkapnya, lihat token ID dan Autentikasi untuk aplikasi yang dihosting di Cloud Run atau Cloud Functions.

  • Token Web JSON yang ditandatangani sendiri (JWT)

    Anda dapat menggunakan JWT yang ditandatangani sendiri untuk mengautentikasi ke beberapa Google API tanpa mendapatkan token akses dari Server Otorisasi. API yang di-deploy dengan Gateway API memerlukan JWT yang ditandatangani sendiri.

  • Blob biner yang ditandatangani sendiri

    Blob yang ditandatangani sendiri berguna dalam skenario saat Anda perlu mengirimkan data biner arbitrer dengan aman, biasanya untuk tujuan autentikasi.

Alur permintaan yang didelegasikan

Alur permintaan yang didelegasikan memungkinkan Anda merangkai permintaan langsung menggunakan satu permintaan tanpa perlu membuat beberapa permintaan langsung secara berurutan. Dalam alur ini, permintaan kredensial akun layanan didelegasikan ke satu atau beberapa akun layanan di rantai delegasi sebelum membuat kredensial untuk akun layanan terakhir. Kredensial yang dihasilkan hanya menampilkan akun layanan terakhir, bukan akun layanan perantara di rantai delegasi.

Setiap akun layanan di rantai delegasi harus memiliki izin yang diperlukan pada akun layanan berikutnya dalam rantai tersebut. Dengan demikian, akun layanan dapat meneruskan permintaan.

Jika satu akun layanan memberikan semua izin yang diperlukan, Anda harus menggunakan alur yang lebih mudah. Alur tersebut dijelaskan dalam Membuat kredensial jangka pendek dari akun layanan.

Sebelum memulai

  • Aktifkan API IAM and Service Account Credentials.

    Mengaktifkan API

  • Pahami akun layanan IAM

  • Jika belum, aktifkan penagihan dan IAM API dengan mengikuti langkah-langkah di quickstart.

  • Identifikasi akun layanan yang akan digunakan di rantai delegasi Anda.

    Anda dapat membuat akun layanan baru dan memasukkannya dalam rantai delegasi jika diperlukan.

Memberikan izin yang diperlukan

Permintaan yang didelegasikan melibatkan lebih dari dua identitas: pemanggil, satu atau beberapa akun layanan di rantai delegasi, dan akun layanan yang kredensialnya dibuat. Dalam alur ini, pertimbangkan identitas berikut:

  • Akun Layanan 1 (SA_1), pemanggil yang mengeluarkan permintaan untuk kredensial jangka pendek.
  • Akun Layanan 2 (SA_2), akun layanan perantara yang akan mendelegasikan permintaan awal ke SA_3. Akun ini hanya meneruskan permintaan dan tidak memberikan akses tambahan pada SA_1 atau SA_3.
  • Akun Layanan 3 (SA_3), akun dengan hak istimewa terbatas yang kredensialnya dibuat.

Untuk mengizinkan delegasi, setiap akun harus memberikan peran Pembuat Token Akun Layanan (roles/iam.serviceAccountTokenCreator) ke akun sebelumnya dalam rantai tersebut.

Dalam contoh khusus ini, SA_1 harus diberi peran Pembuat Token Akun Layanan (roles/iam.serviceAccountTokenCreator) pada SA_2. Contoh ini adalah contoh akun layanan SA_2 yang diperlakukan sebagai resource: saat memberikan peran pada SA_2, Anda mengupdate kebijakan izinnya dengan cara yang sama seperti saat mengupdate resource lainnya.

Dalam alur contoh ini, hanya terdapat satu akun layanan perantara. Untuk mendelegasikan akses melalui lebih dari satu akun layanan, Anda juga harus menetapkan peran ini ke akun layanan lain dalam rantai tersebut.

Berikutnya, SA_2 juga harus diberi peran Pembuat Token Akun Layanan (roles/iam.serviceAccountTokenCreator) pada SA_3. Peran ini memungkinkan SA_2 membuat kredensial jangka pendek untuk SA_3.

Berikut ini adalah langkah menggunakan REST API untuk memberikan peran. Namun, Anda juga dapat menggunakan konsol Google Cloud atau gcloud CLI.

API

Pertama, dapatkan kebijakan izin untuk SA_2 (akun layanan perantara):

Metode serviceAccounts.getIamPolicy mendapatkan kebijakan izin akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda Project ID adalah string alfanumerik, seperti my-project.
  • SA_2: Nama Akun Layanan 2.
  • POLICY_VERSION: Versi kebijakan yang akan ditampilkan. Permintaan harus menentukan versi kebijakan terbaru, yaitu kebijakan versi 3. Lihat Menentukan versi kebijakan saat mendapatkan kebijakan untuk detailnya.

Metode HTTP dan URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy

Meminta isi JSON:

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

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Anda akan menerima respons JSON seperti berikut:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    }
  ]
}

Jika Anda belum memberikan peran ke akun layanan, respons hanya akan berisi nilai etag. Masukkan nilai etag tersebut di langkah berikutnya.

Berikutnya, ubah kebijakan izin untuk memberi SA_1 peran Pembuat Token Akun Layanan (roles/iam.serviceAccountTokenCreator).

Misalnya, untuk mengubah contoh respons dari langkah sebelumnya, Anda dapat menambahkan:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
      ]
    }
  ]
}

Lalu, tulis kebijakan izin yang sudah diupdate untuk SA_2:

Metode serviceAccounts.setIamPolicy menetapkan kebijakan izin yang diupdate untuk akun layanan.

Sebelum menggunakan salah satu dari data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda Project ID adalah string alfanumerik, seperti my-project.
  • SA_2: Nama Akun Layanan 2.
  • POLICY: Representasi JSON dari kebijakan yang ingin Anda tetapkan. Untuk informasi selengkapnya mengenai format kebijakan, lihat Referensi kebijakan.

    Misalnya, untuk menetapkan kebijakan izin yang ditunjukkan di langkah sebelumnya, ganti POLICY dengan kode berikut:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/serviceAccountAdmin",
          "members": [
            "user:admin@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_1@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }
    

Metode HTTP dan URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy

Meminta isi JSON:

{
  "policy": POLICY
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Respons berisi kebijakan izin yang telah diperbarui.

Kini, dapatkan kebijakan izin SA_3 (akun layanan yang kredensialnya dibuat):

Metode serviceAccounts.getIamPolicy mendapatkan kebijakan izin akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda Project ID adalah string alfanumerik, seperti my-project.
  • SA_3: Nama Akun Layanan 3.
  • POLICY_VERSION: Versi kebijakan yang akan ditampilkan. Permintaan harus menentukan versi kebijakan terbaru, yaitu kebijakan versi 3. Lihat Menentukan versi kebijakan saat mendapatkan kebijakan untuk detailnya.

Metode HTTP dan URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com:getIamPolicy

Meminta isi JSON:

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

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Anda akan menerima respons JSON seperti berikut:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    }
  ]
}

Jika Anda belum menetapkan peran ke akun layanan, respons hanya akan berisi nilai etag. Masukkan nilai etag tersebut di langkah berikutnya.

Berikutnya, ubah kebijakan izin untuk memberi SA_2 peran Pembuat Token Akun Layanan (roles/iam.serviceAccountTokenCreator).

Misalnya, untuk mengubah contoh respons dari langkah sebelumnya, Anda dapat menambahkan:

{
  "version": 1,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "role": "roles/serviceAccountAdmin",
      "members": [
        "user:admin@example.com"
      ]
    },
    {
      "role": "roles/iam.serviceAccountTokenCreator",
      "members": [
        "serviceAccount:SA_2@PROJECT_ID.iam.gserviceaccount.com"
      ]
    }
  ]
}

Terakhir, tulis kebijakan izin yang sudah diupdate:

Metode serviceAccounts.setIamPolicy menetapkan kebijakan izin yang diupdate untuk akun layanan.

Sebelum menggunakan salah satu dari data permintaan, lakukan penggantian berikut:

  • PROJECT_ID: Project ID Google Cloud Anda Project ID adalah string alfanumerik, seperti my-project.
  • SA_3: Nama Akun Layanan 3.
  • POLICY: Representasi JSON dari kebijakan yang ingin Anda tetapkan. Untuk informasi selengkapnya mengenai format kebijakan, lihat Referensi kebijakan.

    Misalnya, untuk menetapkan kebijakan izin yang ditunjukkan di langkah sebelumnya, ganti POLICY dengan kode berikut:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/serviceAccountAdmin",
          "members": [
            "user:admin@example.com"
          ]
        },
        {
          "role": "roles/iam.serviceAccountTokenCreator",
          "members": [
            "serviceAccount:SA_2@PROJECT_ID.iam.gserviceaccount.com"
          ]
        }
      ]
    }
    

Metode HTTP dan URL:

POST https://iam.googleapis.com/v1/projects/PROJECT_ID/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com:setIamPolicy

Meminta isi JSON:

{
  "policy": POLICY
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Respons berisi kebijakan izin yang telah diperbarui.

Meminta kredensial jangka pendek

Setelah memberikan peran yang sesuai pada setiap identitas, Anda dapat meminta kredensial jangka pendek untuk akun layanan yang diinginkan. Berikut adalah jenis kredensial yang didukung:

Guna memahami cara menentukan rantai delegasi untuk permintaan ini, lihat bagian Menentukan rantai delegasi di halaman ini.

Membuat token akses OAuth 2.0

Secara default, token akses OAuth 2.0 berlaku selama maksimum 1 jam (3.600 detik). Namun, Anda dapat memperpanjang masa aktif maksimum token ini menjadi 12 jam (43.200 detik). Untuk melakukannya, identifikasi akun layanan yang memerlukan perpanjangan masa aktif token, lalu tambahkan akun layanan ini ke kebijakan organisasi yang mencakup batasan daftar constraints/iam.allowServiceAccountCredentialLifetimeExtension. Masa aktif token akan dapat ditetapkan hingga 43.200 detik saat Anda membuat token untuk akun layanan ini.

Untuk membuat token akses OAuth 2.0 pada akun layanan, lakukan langkah-langkah berikut:

API

Metode Service Account Credentials API serviceAccounts.generateAccessToken menghasilkan token akses OAuth 2.0 pada akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • SA_NAME: Nama akun layanan yang tokennya ingin Anda buat.
  • PROJECT_ID: Project ID Google Cloud Anda. Project ID adalah string alfanumerik, seperti my-project.
  • DELEGATES: Jika Anda menggunakan alur permintaan yang didelegasikan, lihat Menetapkan rantai delegasi di halaman ini. Jika Anda menggunakan alur permintaan langsung tanpa delegasi, hapus kolom delegates di isi permintaan.
  • LIFETIME: Durasi hingga masa aktif token akses berakhir, tulis dalam detik. Contoh, 300s.

    Secara default, masa aktif token maksimum adalah 1 jam (3.600 detik). Untuk memperpanjang masa aktif maksimum token ini menjadi 12 jam (43.200 detik), tambahkan akun layanan ke kebijakan organisasi yang menyertakan batasan daftar constraints/iam.allowServiceAccountCredentialLifetimeExtension.

Metode HTTP dan URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken

Meminta isi JSON:

{
  "delegates": [
    DELEGATES
  ],
  "scope": [
    "https://www.googleapis.com/auth/cloud-platform"
  ],
  "lifetime": "LIFETIME"
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Jika permintaan generateAccessToken berhasil, isi respons akan memuat token akses OAuth 2.0 dan waktu habis masa berlaku. accessToken akan dapat digunakan untuk mengautentikasi permintaan atas nama akun layanan hingga expireTime sudah tercapai:

{
  "accessToken": "eyJ0eXAi...NiJ9",
  "expireTime": "2020-04-07T15:01:23.045123456Z"
}

Membuat token ID OpenID Connect

Token ID OpenID Connect berlaku selama 1 jam (3.600 detik). Untuk membuat token ID pada akun layanan, lakukan langkah-langkah berikut:

API

Metode Service Account Credentials API serviceAccounts.generateIdToken menghasilkan token ID OIDC pada akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • PRIV_SA: Alamat email akun layanan yang memiliki hak istimewa tempat token yang berlaku singkat dibuat.
  • AUDIENCE_NAME: Audiens untuk token, biasanya URL aplikasi atau layanan tempat token akan digunakan untuk mengakses.

Metode HTTP dan URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/PRIV_SA:generateIdToken

Meminta isi JSON:

{
  "audience": "AUDIENCE_NAME",
  "includeEmail": "true"
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Jika permintaan generateId berhasil, isi permintaan akan memuat token ID yang berlaku selama 1 jam. token kemudian dapat digunakan untuk mengautentikasi permintaan atas nama akun layanan:

{
  "token": "eyJ0eXAi...NiJ9"
}

Membuat Token Web JSON yang ditandatangani sendiri (JWT)

Token Web JSON yang ditandatangani sendiri (JWTs) berguna dalam berbagai skenario, seperti:

  • Mengautentikasi panggilan ke Google API seperti yang dijelaskan dalam Panduan Autentikasi Google.
  • Berkomunikasi antar Google Cloud atau layanan non-Google dengan aman, seperti aplikasi App Engine. Dalam skenario ini, satu aplikasi dapat menandatangani token yang dapat diverifikasi oleh aplikasi lain untuk tujuan autentikasi.
  • Memperlakukan akun layanan sebagai penyedia identitas dengan menandatangani JWT yang berisi klaim arbitrer mengenai pengguna, akun, atau perangkat.

Untuk membuat JWT yang ditandatangani sendiri pada akun layanan, lakukan langkah-langkah berikut:

API

Metode Service Account Credentials API serviceAccounts.signJwt menandatangani JWT menggunakan kunci pribadi yang dikelola sistem pada akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • SA_NAME: Nama akun layanan yang tokennya ingin Anda buat.
  • PROJECT_ID: Project ID Google Cloud Anda. Project ID adalah string alfanumerik, seperti my-project.
  • DELEGATES: Jika Anda menggunakan alur permintaan yang didelegasikan, lihat Menetapkan rantai delegasi di halaman ini. Jika Anda menggunakan alur permintaan langsung tanpa delegasi, hapus kolom delegates di isi permintaan.
  • JWT_PAYLOAD: Payload JWT yang akan ditandatangani, yaitu objek JSON berisi Kumpulan Klaim JWT. Sertakan klaim yang diperlukan untuk kasus penggunaan yang Anda inginkan dan untuk memenuhi persyaratan validasi untuk layanan yang Anda panggil. Jika Anda memanggil Google API, lihat Panduan Autentikasi Google untuk mengetahui persyaratan klaimnya.

    Klaim exp (waktu habis masa berlaku) tidak boleh lebih dari 12 jam ke depan. Jika Anda memanggil Google API, klaim exp harus ditetapkan tidak boleh lebih dari 1 jam ke depan.

    Contoh payload berikut berisi klaim untuk memanggil Google API, dengan EXP adalah stempel waktu bilangan bulat yang menunjukkan waktu habis masa berlaku:

    { \"iss\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"sub\": \"SA_NAME@PROJECT_ID.iam.gserviceaccount.com\", \"aud\": \"https://firestore.googleapis.com/\", \"iat\": 1529350000, \"exp\": EXP }

Metode HTTP dan URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signJwt

Meminta isi JSON:

{
  "delegates": [
    DELEGATES
  ],
  "payload": "JWT_PAYLOAD"
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Jika permintaan signJwt berhasil, isi respons berisi JWT yang ditandatangani dan ID kunci penandatanganan yang digunakan untuk menandatangani JWT. Anda dapat menggunakan nilai signedJwt sebagai token pemilik untuk secara langsung mengautentikasi permintaan atas nama akun layanan. Token berlaku hingga waktu berakhir masa aktif ditetapkan dalam permintaan:

{
  "keyId": "42ba1e...fc0a",
  "signedJwt": "eyJ0eXAi...NiJ9"
}

Membuat blob yang ditandatangani sendiri

Blob yang ditandatangani sendiri berguna dalam skenario saat Anda perlu mengirimkan data biner arbitrer dengan aman, biasanya untuk tujuan autentikasi. Misalnya, jika Anda ingin menggunakan jenis protokol/token kustom (bukan JWT), Anda dapat memasukkan data tersebut dalam blob yang ditandatangani untuk digunakan oleh layanan downstream.

Untuk membuat blob yang ditandatangani pada akun layanan, lakukan langkah-langkah berikut:

API

Metode Service Account Credentials API serviceAccounts.signBlob menandatangani blob menggunakan kunci pribadi yang dikelola sistem pada akun layanan.

Sebelum menggunakan salah satu data permintaan, lakukan penggantian berikut:

  • SA_NAME: Nama akun layanan yang tokennya ingin Anda buat.
  • PROJECT_ID: Project ID Google Cloud Anda. Project ID adalah string alfanumerik, seperti my-project.
  • DELEGATES: Jika Anda menggunakan alur permintaan yang didelegasikan, lihat Menetapkan rantai delegasi di halaman ini. Jika Anda menggunakan alur permintaan langsung tanpa delegasi, hapus kolom delegates di isi permintaan.
  • BLOB_PAYLOAD: String byte berenkode base64. Misalnya, VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wZWQgb3ZlciB0aGUgbGF6eSBkb2cu.

Metode HTTP dan URL:

POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:signBlob

Meminta isi JSON:

{
  "delegates": [
    DELEGATES
  ],
  "payload": "BLOB_PAYLOAD"
}

Untuk mengirim permintaan Anda, perluas salah satu opsi berikut:

Jika permintaan signBlob berhasil, isi respons akan memuat blob yang ditandatangani dan ID kunci penandatanganan yang digunakan untuk menandatangani blob. Anda dapat menggunakan nilai signedBlob sebagai token pemilik untuk secara langsung mengautentikasi permintaan atas nama akun layanan. Token berlaku hingga masa berlaku kunci pribadi yang dikelola sistem pada akun layanan berakhir. ID kunci adalah nilai kolom keyId dalam respons.

{
  "keyId": "42ba1e...fc0a",
  "signedBlob": "eyJ0eXAi...NiJ9"
}

Menetapkan rantai delegasi

Saat menggunakan alur permintaan yang didelegasikan untuk membuat kredensial akun layanan jangka pendek, isi permintaan untuk setiap API harus menetapkan rantai delegasi akun layanan dalam urutan yang benar, serta dalam format berikut:

projects/-/serviceAccounts/SA_ID

Ganti SA_ID dengan ID numerik unik akun layanan atau alamat email akun layanan.

Misalnya, dalam rantai delegasi melalui SA_1 (pemanggil) ke SA_2 (delegasi) ke SA_3 (delegasi) ke SA_4, kolom delegates[] akan berisi SA_2 dan SA_3 dalam urutan berikut:

{
  "delegates": [
    "projects/-/serviceAccounts/SA_2@PROJECT_ID.iam.gserviceaccount.com",
    "projects/-/serviceAccounts/SA_3@PROJECT_ID.iam.gserviceaccount.com"
  ]
}

Pemanggil dan akun layanan yang kredensialnya dibuat tidak termasuk dalam rantai delegasi.