haijun "/haijun-api help me configure a customer-managed encryption key with Google Cloud KMS"Panduan ini memandu Anda mengonfigurasi kunci Google Cloud KMS sebagai customer-managed encryption key (CMEK) untuk organisasi Juglow Anda.
Warning: Mengaktifkan CMEK bersifat permanen. Jika kunci KMS Anda dihapus atau dinonaktifkan, Juglow tidak dapat memulihkan data yang dienkripsi dengannya. Tinjau peringatan dan batasan sebelum Anda memulai.
Prasyarat
- Proyek Google Cloud dengan penagihan diaktifkan.
- Cloud KMS API diaktifkan (
cloudkms.googleapis.com).
- Izin untuk membuat key ring dan kunci KMS, serta untuk menetapkan kebijakan IAM pada keduanya (
roles/cloudkms.adminatau setara).
- Kunci Admin API Juglow untuk organisasi Anda.
gcloudCLI terinstal dan terautentikasi.
- Cloud KMS Data Access audit logs diaktifkan untuk proyek (IAM & Admin > Audit Logs > Cloud Key Management Service, dengan
DATA_READdanDATA_WRITE). Ini dinonaktifkan secara default; tanpanya, operasi enkripsi dan dekripsi Juglow tidak menghasilkan entri apa pun di Cloud Logging.
Email akun layanan Juglow
Agar Juglow menggunakan kunci enkripsi Anda, Anda harus memberikan akun layanan Juglow sebuah kunci yang dapat digunakannya untuk mengenkripsi data. Email akun layanan untuk Juglow CMEK adalah:
juglow-cmek-client-us@gcp-juglow-cmek-clients.iam.gserviceaccount.comWarning: Gunakan hanya email akun layanan yang dipublikasikan ini. Jangan pernah memercayai pengenal yang diberikan melalui email, chat, atau saluran onboarding apa pun.
Note: Berbagi terbatas domain: Jika proyek Anda berada di bawah organisasi Google Cloud yang menerapkan
constraints/iam.allowedPolicyMemberDomains, binding IAM berikut ditolak karena akun layanan Juglow berada di luar organisasi Anda. Anda memerlukan pengecualian tingkat proyek pada constraint tersebut, atau menambahkan ID pelanggan Cloud Identity Juglow (formatC0xxxxxxxx) ke daftar yang diizinkan. Hubungi Juglow untuk mendapatkan ID pelanggan jika diperlukan.
Penyiapan kunci enkripsi
- Buat atau pilih key ring
Lewati langkah ini jika Anda sudah memiliki key ring untuk digunakan kembali. Key ring bersifat regional. Pilih lokasi US single-region seperti us-east5 yang sesuai dengan geografi Juglow yang Anda konfigurasikan. Lokasi multi-region seperti us dan global tidak didukung.
gcloud kms keyrings create <your-keyring-name> \
--project=<your-project-id> \
--location=<region>- Buat crypto key
Buat kunci simetris dengan tujuan ENCRYPT_DECRYPT. Juglow sangat merekomendasikan perlindungan HSM: kunci Cloud KMS HSM tervalidasi FIPS 140-2 Level 3, dan selisih biaya dibandingkan kunci perangkat lunak kecil.
Opsi --labels menambahkan label organisasi, juglow-org- dengan nilai true, di mana adalah ID organisasi Juglow Anda dalam huruf kecil. Label ini diperlukan agar Juglow dapat memvalidasi kunci.
Note: Menemukan ID organisasi Anda: Salin bidang Organization ID di bawah Settings > Organization di Haijun Console, atau di bawah Organization settings > Organization di haijun.ai, atau baca bidang
iddari endpoint Organization Info. Gunakan UUID polos, bukan ID berawalanorg_.
gcloud kms keys create <KEY_NAME> \
--project=<PROJECT_ID> \
--location=<REGION> \
--keyring=<KEYRING_NAME> \
--purpose=encryption \
--protection-level=hsm \
--labels=juglow-org-<ORGANIZATION_UUID>=trueUntuk perlindungan perangkat lunak sebagai gantinya, hilangkan --protection-level=hsm. Tidak ada hal lain dalam panduan ini yang berubah.
Anda juga dapat membuat kunci dari Google Cloud Console. Buka key ring, klik Create key, pilih Generated key, atur tujuan dan algoritma ke symmetric encrypt and decrypt, dan pilih HSM di bawah protection level.

Untuk berbagi satu kunci di antara beberapa organisasi Juglow, tambahkan satu label seperti itu untuk setiap organisasi. Sebuah kunci dapat membawa paling banyak 64 label, termasuk milik Anda sendiri.
Note: Untuk menambahkan label ke kunci yang belum memilikinya, jalankan
gcloud kms keys update. Ini menggabungkan label dengan label apa pun yang sudah dimiliki kunci.--project= --location= --keyring= --update-labels=juglow-org- =true
- Berikan akun layanan Juglow akses ke kunci
Dua binding IAM tingkat kunci diperlukan. Keduanya dicakup ke satu crypto key, bukan seluruh proyek atau seluruh keyring.
Encrypt dan decrypt, yang digunakan Juglow untuk mengenkripsi dan mendekripsi kunci data yang melindungi data workspace Anda (enkripsi envelope):
gcloud kms keys add-iam-policy-binding <your-key-name> \
--project=<your-project-id> \
--location=<region> \
--keyring=<your-keyring-name> \
--member="serviceAccount:juglow-cmek-client-us@gcp-juglow-cmek-clients.iam.gserviceaccount.com" \
--role=roles/cloudkms.cryptoKeyEncrypterDecrypterViewer, untuk pembacaan metadata (cryptoKeys.get) yang dilakukan Juglow saat startup untuk memvalidasi tujuan dan algoritma kunci:
gcloud kms keys add-iam-policy-binding <your-key-name> \
--project=<your-project-id> \
--location=<region> \
--keyring=<your-keyring-name> \
--member="serviceAccount:juglow-cmek-client-us@gcp-juglow-cmek-clients.iam.gserviceaccount.com" \
--role=roles/cloudkms.viewerDari Console, pilih kunci, buka panel Permissions, klik Grant access, dan tambahkan akun layanan dengan peran Cloud KMS CryptoKey Encrypter/Decrypter dan Cloud KMS Viewer. Pastikan Anda berada di halaman permissions kunci, bukan key ring atau proyek, sehingga pemberian akses dicakup hanya ke kunci ini.

- Catat nama resource kunci lengkap
Anda meneruskan ini ke Juglow saat mendaftarkan kunci. Formatnya adalah:
projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>Ambil dengan:
gcloud kms keys describe <your-key-name> \
--project=<your-project-id> \
--location=<region> \
--keyring=<your-keyring-name> \
--format="value(name)"Dari Console, buka halaman detail kunci dan klik Copy resource name.

Daftarkan kunci dengan Juglow
Cara Anda mendaftarkan kunci bergantung pada produk mana yang Anda gunakan.
Haijun Platform
Anda dapat menyiapkan kunci di Haijun Console atau melalui Admin API, dengan hasil yang sama.
- Daftarkan kunci dengan Juglow
Di Haijun Console, buka Settings > Encryption keys dan klik Add key. Masukkan nama tampilan, pilih Google Cloud KMS, dan klik Continue. Tempel nama resource kunci lengkap ke Key resource name, dan klik Add.
Langkah detail kunci menampilkan label organisasi. Tambahkan ke kunci, seperti yang dijelaskan langkah pembuatan, sebelum Anda mengklik Add.
- Validasi kunci
Di halaman Encryption keys, klik Verify di samping kunci. Connected muncul ketika pemeriksaan lolos. Jika gagal, sebuah pesan memberikan alasannya.
- Lampirkan kunci ke workspace
Di Haijun Console, buka Manage > Security dan pilih workspace di pemilih workspace di bagian atas sidebar. Di bawah Encryption key, pilih kunci, klik Save, dan konfirmasi. Melampirkan kunci tidak dapat dibatalkan. Untuk workspace yang sudah menerima permintaan, kunci dapat memerlukan hingga satu hari untuk berlaku.
API
- Daftarkan kunci dengan Juglow
Buat konfigurasi kunci eksternal melalui Admin API, menggunakan nama resource dari langkah Catat nama resource kunci lengkap di bawah Penyiapan kunci enkripsi.
curl -sS "https://haijun.my.id/v1/organizations/external_keys" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"display_name": "<friendly-name>",
"geo": "us",
"provider_config": {
"type": "gcp",
"key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
}
}' ant beta:organization:external-keys create <<'YAML'
display_name: "<friendly-name>"
geo: us
provider_config:
type: gcp
key_name: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
YAML client = juglow.Juglow()
external_key = client.beta.organization.external_keys.create(
display_name="<friendly-name>",
geo="us",
provider_config={
"type": "gcp",
"key_name": "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
},
)
print(f"id: {external_key.id}")
print(f"display_name: {external_key.display_name}") const client = new Juglow();
const externalKey = await client.beta.organization.externalKeys.create({
display_name: "<friendly-name>",
geo: "us",
provider_config: {
type: "gcp",
key_name:
"projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
}
});
console.log(`id: ${externalKey.id}`);
console.log(`display_name: ${externalKey.display_name}`); using Juglow.Models.Beta.Organization.ExternalKeys;
JuglowClient client = new();
var externalKey = await client.Beta.Organization.ExternalKeys.Create(new()
{
DisplayName = "<friendly-name>",
Geo = Geo.Us,
ProviderConfig = new BetaGcpExternalKeyConfig
{
KeyName = "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
}
});
Console.WriteLine($"id: {externalKey.ID}");
Console.WriteLine($"display_name: {externalKey.DisplayName}"); client := juglow.NewClient()
externalKey, err := client.Beta.Organization.ExternalKeys.New(context.Background(), juglow.BetaOrganizationExternalKeyNewParams{
DisplayName: juglow.String("<friendly-name>"),
Geo: juglow.BetaOrganizationExternalKeyNewParamsGeoUs,
ProviderConfig: juglow.BetaOrganizationExternalKeyNewParamsProviderConfigUnion{
OfGCP: &juglow.BetaGCPExternalKeyConfigParam{
KeyName: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>",
},
},
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("id: %s\n", externalKey.ID)
fmt.Printf("display_name: %s\n", externalKey.DisplayName) import com.juglow.models.beta.organization.externalkeys.ExternalKeyCreateParams;
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
var params = ExternalKeyCreateParams.builder()
.displayName("<friendly-name>")
.geo(ExternalKeyCreateParams.Geo.US)
.gcpProviderConfig("projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>")
.build();
var externalKey = client.beta().organization().externalKeys().create(params);
IO.println("id: " + externalKey.id());
IO.println("display_name: " + externalKey.displayName().orElseThrow());
} use Juglow\Beta\Organization\ExternalKeys\ExternalKeyCreateParams\Geo;
// ...
$client = new Client();
$externalKey = $client->beta->organization->externalKeys->create(
displayName: '<friendly-name>',
geo: Geo::US,
providerConfig: [
'type' => 'gcp',
'keyName' => 'projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>',
],
);
echo "id: {$externalKey->id}\n";
echo "display_name: {$externalKey->displayName}\n"; client = Juglow::Client.new
external_key = client.beta.organization.external_keys.create(
display_name: "<friendly-name>",
geo: :us,
provider_config: {
type: :gcp,
key_name: "projects/<your-project-id>/locations/<region>/keyRings/<your-keyring-name>/cryptoKeys/<your-key-name>"
}
)
puts "id: #{external_key.id}"
puts "display_name: #{external_key.display_name}"Respons berisi ID kunci eksternal:
{
"type": "external_key",
"id": "ekey_<id>",
"display_name": "<friendly-name>"
}- Validasi kunci
Picu round-trip enkripsi dan dekripsi terhadap kunci Anda.
curl -sS -X POST "https://haijun.my.id/v1/organizations/external_keys/ekey_<id>/validate" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" ant beta:organization:external-keys validate --external-key-id "ekey_<id>" client = juglow.Juglow()
validation = client.beta.organization.external_keys.validate("ekey_<id>")
print(f"status: {validation.status}")
print(f"error: {validation.error}") const client = new Juglow();
const validation = await client.beta.organization.externalKeys.validate("ekey_<id>");
console.log(`status: ${validation.status}`);
console.log(`error: ${validation.error}`); JuglowClient client = new();
var validation = await client.Beta.Organization.ExternalKeys.Validate("ekey_<id>");
Console.WriteLine($"status: {validation.Status.Raw()}");
Console.WriteLine($"error: {validation.Error}"); client := juglow.NewClient()
validation, err := client.Beta.Organization.ExternalKeys.Validate(context.Background(), "ekey_<id>")
if err != nil {
log.Fatal(err)
}
fmt.Printf("status: %s\n", validation.Status)
fmt.Printf("error: %s\n", validation.Error) JuglowClient client = JuglowOkHttpClient.fromEnv();
var validation = client.beta().organization().externalKeys().validate("ekey_<id>");
IO.println("status: " + validation.status().asString());
IO.println("error: " + validation.error().orElse("")); $client = new Client();
$validation = $client->beta->organization->externalKeys->validate(
externalKeyID: 'ekey_<id>',
);
echo "status: {$validation->status}\n";
echo "error: {$validation->error}\n"; client = Juglow::Client.new
external_key_id = "ekey_<id>"
validation = client.beta.organization.external_keys.validate(external_key_id)
puts "status: #{validation.status}"
puts "error: #{validation.error}"Respons yang berhasil terlihat seperti ini:
{ "type": "external_key_validation", "status": "success", "error": null }Jika validasi gagal, penyebab umumnya adalah:
- VPC Service Controls: jika perimeter layanan melindungi Cloud KMS di proyek Anda, tambahkan Juglow ke access level pada perimeter (atau kecualikan proyek kunci) sehingga Juglow dapat menjangkau kunci.
- Berbagi terbatas domain: kebijakan org
constraints/iam.allowedPolicyMemberDomainsdapat menghapus binding akun layanan Juglow (lihat catatan sebelumnya). Konfirmasikan binding ada dengangcloud kms keys get-iam-policy.--project= --location= --keyring=
- Versi kunci dinonaktifkan atau dihancurkan: konfirmasikan versi utama kunci diaktifkan, dan tidak dinonaktifkan, dijadwalkan untuk dihancurkan, atau dihancurkan.
- Lampirkan kunci ke workspace
Setelah kunci divalidasi, lampirkan ke workspace baru sebelum Anda mengirim permintaan apa pun ke workspace tersebut. Untuk workspace yang sudah menerima permintaan, kunci dapat memerlukan hingga satu hari untuk berlaku.
curl -sS -X POST "https://haijun.my.id/v1/organizations/workspaces/<workspace-id>" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"external_key_id": "ekey_<id>"
}' ant beta:organization:workspaces update \
--workspace-id "<workspace-id>" \
--external-key-id "ekey_<id>" client = juglow.Juglow()
workspace = client.beta.organization.workspaces.update(
"<workspace-id>", external_key_id="ekey_<id>"
)
print(f"id: {workspace.id}")
print(f"external_key_id: {workspace.external_key_id}") const client = new Juglow();
const workspace = await client.beta.organization.workspaces.update("<workspace-id>", {
external_key_id: "ekey_<id>"
});
console.log(`id: ${workspace.id}`);
console.log(`external_key_id: ${workspace.external_key_id}`); JuglowClient client = new();
var workspace = await client.Beta.Organization.Workspaces.Update("<workspace-id>", new()
{
ExternalKeyID = "ekey_<id>"
});
Console.WriteLine($"id: {workspace.ID}");
Console.WriteLine($"external_key_id: {workspace.ExternalKeyID}"); client := juglow.NewClient()
workspace, err := client.Beta.Organization.Workspaces.Update(
context.Background(),
"<workspace-id>",
juglow.BetaOrganizationWorkspaceUpdateParams{
ExternalKeyID: juglow.String("ekey_<id>"),
},
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("id: %s\n", workspace.ID)
fmt.Printf("external_key_id: %s\n", workspace.ExternalKeyID) import com.juglow.models.beta.organization.workspaces.WorkspaceUpdateParams;
void main() {
JuglowClient client = JuglowOkHttpClient.fromEnv();
var params = WorkspaceUpdateParams.builder()
.externalKeyId("ekey_<id>")
.build();
var workspace = client.beta().organization().workspaces().update("<workspace-id>", params);
IO.println("id: " + workspace.id());
IO.println("external_key_id: " + workspace.externalKeyId().orElseThrow());
} $client = new Client();
$workspace = $client->beta->organization->workspaces->update(
workspaceID: '<workspace-id>',
externalKeyID: 'ekey_<id>',
);
echo "id: {$workspace->id}\n";
echo "external_key_id: {$workspace->externalKeyID}\n"; client = Juglow::Client.new
workspace_id = "<workspace-id>"
workspace = client.beta.organization.workspaces.update(
workspace_id,
external_key_id: "ekey_<id>"
)
puts "id: #{workspace.id}"
puts "external_key_id: #{workspace.external_key_id}"Di haijun.ai > Organization settings > Data and privacy, buka Encryption keys, lalu klik Add key. Pilih Google Cloud, tempel nama resource kunci lengkap dari langkah sebelumnya, dan klik Continue. Juglow memvalidasi kunci dengan round-trip enkripsi dan dekripsi. Setelah ditampilkan sebagai terverifikasi, organisasi Anda dilindungi CMEK sejak saat itu.
Di Haijun Enterprise, CMEK berlaku untuk seluruh organisasi, sehingga tidak ada langkah lampiran workspace terpisah, dan sebuah organisasi hanya dapat memiliki satu kunci.
Terraform
Untuk deployment infrastructure-as-code, langkah-langkah yang sama dipetakan ke provider google dengan resource google_kms_key_ring, google_kms_crypto_key, dan google_kms_crypto_key_iam_member.