/* * Copyright (c) 2017 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.example; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.cloudkms.v1.CloudKMS; import com.google.api.services.cloudkms.v1.CloudKMSScopes; import com.google.api.services.cloudkms.v1.model.Binding; import com.google.api.services.cloudkms.v1.model.CryptoKey; import com.google.api.services.cloudkms.v1.model.CryptoKeyVersion; import com.google.api.services.cloudkms.v1.model.DestroyCryptoKeyVersionRequest; import com.google.api.services.cloudkms.v1.model.KeyRing; import com.google.api.services.cloudkms.v1.model.ListCryptoKeyVersionsResponse; import com.google.api.services.cloudkms.v1.model.ListCryptoKeysResponse; import com.google.api.services.cloudkms.v1.model.ListKeyRingsResponse; import com.google.api.services.cloudkms.v1.model.Policy; import com.google.api.services.cloudkms.v1.model.SetIamPolicyRequest; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import java.io.IOException; import java.util.Collections; import java.util.List; public class Snippets { /** * Creates an authorized CloudKMS client service using Application Default Credentials. * * @return an authorized CloudKMS client * @throws IOException if there's an error getting the default credentials. */ public static CloudKMS createAuthorizedClient() throws IOException { // Create the credential HttpTransport transport = new NetHttpTransport(); JsonFactory jsonFactory = new JacksonFactory(); // Authorize the client using Application Default Credentials // @see https://g.co/dv/identity/protocols/application-default-credentials GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory); // Depending on the environment that provides the default credentials (e.g. Compute Engine, App // Engine), the credentials may require us to specify the scopes we need explicitly. // Check for this case, and inject the scope if required. if (credential.createScopedRequired()) { credential = credential.createScoped(CloudKMSScopes.all()); } return new CloudKMS.Builder(transport, jsonFactory, credential) .setApplicationName("CloudKMS snippets") .build(); } // [START kms_create_keyring] /** * Creates a new key ring with the given id. */ public static KeyRing createKeyRing(String projectId, String ringId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the location associated with the KeyRing. String parent = String.format("projects/%s/locations/%s", projectId, location); // Create the KeyRing for your project. KeyRing keyring = kms.projects().locations().keyRings() .create(parent, new KeyRing()) .setKeyRingId(ringId) .execute(); System.out.println(keyring); return keyring; } // [END kms_create_keyring] // [START kms_create_cryptokey] /** * Creates a new crypto key with the given id. */ public static CryptoKey createCryptoKey(String projectId, String ringId, String keyId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the location associated with the KeyRing. String parent = String.format( "projects/%s/locations/%s/keyRings/%s", projectId, location, ringId); // This will allow the API access to the key for encryption and decryption. String purpose = "ENCRYPT_DECRYPT"; CryptoKey cryptoKey = new CryptoKey(); cryptoKey.setPurpose(purpose); // Create the CryptoKey for your project. CryptoKey createdKey = kms.projects().locations().keyRings().cryptoKeys() .create(parent, cryptoKey) .setCryptoKeyId(keyId) .execute(); System.out.println(createdKey); return createdKey; } // [END kms_create_cryptokey] // [START kms_create_cryptokey_version] /** * Creates a new crypto key version for the given id. */ public static void createCryptoKeyVersion( String projectId, String ringId, String keyId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String cryptoKeys = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, ringId, keyId); CryptoKeyVersion version = new CryptoKeyVersion(); CryptoKeyVersion newVersion = kms.projects().locations().keyRings().cryptoKeys() .cryptoKeyVersions() .create(cryptoKeys, version) .execute(); System.out.println(newVersion); } // [END kms_create_cryptokey_version] // [START kms_disable_cryptokey_version] /** * Disables the given version of the crypto key. */ public static CryptoKeyVersion disableCryptoKeyVersion( String projectId, String ringId, String keyId, String version) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey version String cryptoKeyVersion = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", projectId, location, ringId, keyId, version); CryptoKeyVersion newVersionState = new CryptoKeyVersion() .setState("DISABLED"); CryptoKeyVersion response = kms.projects().locations().keyRings().cryptoKeys() .cryptoKeyVersions() .patch(cryptoKeyVersion, newVersionState) .setUpdateMask("state") .execute(); System.out.println(response); return response; } // [END kms_disable_cryptokey_version] // [START kms_destroy_cryptokey_version] /** * Marks the given version of a crypto key to be destroyed at a scheduled future point. */ public static CryptoKeyVersion destroyCryptoKeyVersion( String projectId, String ringId, String keyId, String version) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey version String cryptoKeyVersion = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s/cryptoKeyVersions/%s", projectId, location, ringId, keyId, version); DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest(); CryptoKeyVersion destroyed = kms.projects().locations().keyRings().cryptoKeys() .cryptoKeyVersions() .destroy(cryptoKeyVersion, destroyRequest) .execute(); System.out.println(destroyed); return destroyed; } // [END kms_destroy_cryptokey_version] // [START kms_get_cryptokey_policy] /** * Retrieves the IAM policy for the given crypto key. */ public static Policy getCryptoKeyPolicy(String projectId, String ringId, String keyId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String cryptoKey = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, ringId, keyId); // Get the current IAM policy and add the new account to it. Policy iamPolicy = kms.projects().locations().keyRings().cryptoKeys() .getIamPolicy(cryptoKey) .execute(); System.out.println(iamPolicy.getBindings()); return iamPolicy; } // [END kms_get_cryptokey_policy] // [START kms_get_keyring_policy] /** * Retrieves the IAM policy for the given crypto key. */ public static Policy getKeyRingPolicy(String projectId, String ringId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the keyring String keyring = String.format( "projects/%s/locations/%s/keyRings/%s", projectId, location, ringId); // Get the current IAM policy and add the new account to it. Policy iamPolicy = kms.projects().locations().keyRings() .getIamPolicy(keyring) .execute(); System.out.println(iamPolicy.getBindings()); return iamPolicy; } // [END kms_get_keyring_policy] // [START kms_add_member_to_cryptokey_policy] /** * Adds the given member to the given key, with the given role. * * @param ringId The id of the keyring. * @param keyId The id of the crypto key. * @param member The member to add. Must be in the proper format, eg: * * allUsers * user:$userEmail * serviceAccount:$serviceAccountEmail * * See https://g.co/cloud/kms/docs/reference/rest/v1/Policy#binding * for more details. * * @param role Must be in one of the following formats: * roles/[role] * organizations/[organizationId]/roles/[role] * projects/[projectId]/roles/[role] * * See https://g.co/cloud/iam/docs/understanding-roles * for available values for [role]. */ public static Policy addMemberToCryptoKeyPolicy( String projectId, String ringId, String keyId, String member, String role) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey version String cryptoKey = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, ringId, keyId); // Get the current IAM policy Policy iamPolicy = getCryptoKeyPolicy(projectId, ringId, keyId); // Add the new account to it. Binding newBinding = new Binding() .setRole(role) .setMembers(Collections.singletonList(member)); List<Binding> bindings = iamPolicy.getBindings(); if (null == bindings) { bindings = Collections.singletonList(newBinding); } else { bindings.add(newBinding); } iamPolicy.setBindings(bindings); // Set the new IAM Policy. Policy newIamPolicy = kms.projects().locations().keyRings() .cryptoKeys() .setIamPolicy(cryptoKey, new SetIamPolicyRequest().setPolicy(iamPolicy)) .execute(); System.out.println("Response: " + newIamPolicy); return newIamPolicy; } // [END kms_add_member_to_cryptokey_policy] // [START kms_add_member_to_keyring_policy] /** * Adds the given member to the given keyring, with the given role. * * @param ringId The id of the keyring. * @param member The member to add. Must be in the proper format, eg: * * allUsers * user:$userEmail * serviceAccount:$serviceAccountEmail * * See https://g.co/cloud/kms/docs/reference/rest/v1/Policy#binding * for more details. * * @param role Must be in one of the following formats: * roles/[role] * organizations/[organizationId]/roles/[role] * projects/[projectId]/roles/[role] * * See https://g.co/cloud/iam/docs/understanding-roles * for available values for [role]. */ public static Policy addMemberToKeyRingPolicy( String projectId, String ringId, String member, String role) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the keyring version String keyring = String.format( "projects/%s/locations/%s/keyRings/%s", projectId, location, ringId); // Get the current IAM policy Policy iamPolicy = getKeyRingPolicy(projectId, ringId); // Add the new account to it. Binding newBinding = new Binding() .setRole(role) .setMembers(Collections.singletonList(member)); List<Binding> bindings = iamPolicy.getBindings(); if (null == bindings) { bindings = Collections.singletonList(newBinding); } else { bindings.add(newBinding); } iamPolicy.setBindings(bindings); // Set the new IAM Policy. Policy newIamPolicy = kms.projects().locations() .keyRings() .setIamPolicy(keyring, new SetIamPolicyRequest().setPolicy(iamPolicy)) .execute(); System.out.println("Response: " + newIamPolicy); return newIamPolicy; } // [END kms_add_member_to_keyring_policy] // [START kms_remove_member_from_cryptokey_policy] /** * Removes the given member from the given policy. */ public static Policy removeMemberFromCryptoKeyPolicy( String projectId, String ringId, String keyId, String member, String role) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String cryptoKey = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, ringId, keyId); // Get the current IAM policy and add the new account to it. Policy iamPolicy = getCryptoKeyPolicy(projectId, ringId, keyId); if (null == iamPolicy.getBindings()) { // Nothing to remove return null; } // Filter out the given member for (Binding b : iamPolicy.getBindings()) { if (role.equals(b.getRole()) && b.getMembers().contains(member)) { b.getMembers().removeAll(Collections.singletonList(member)); break; } } // Set the new IAM Policy. Policy newIamPolicy = kms.projects().locations().keyRings() .cryptoKeys() .setIamPolicy(cryptoKey, new SetIamPolicyRequest().setPolicy(iamPolicy)) .execute(); System.out.println("Response: " + newIamPolicy); return newIamPolicy; } // [END kms_remove_member_from_cryptokey_policy] // [START kms_remove_member_from_keyring_policy] /** * Removes the given member from the given policy. */ public static Policy removeMemberFromKeyRingPolicy( String projectId, String ringId, String member, String role) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String cryptoKey = String.format( "projects/%s/locations/%s/keyRings/%s", projectId, location, ringId); // Get the current IAM policy and add the new account to it. Policy iamPolicy = getKeyRingPolicy(projectId, ringId); // Filter out the given member for (Binding b : iamPolicy.getBindings()) { if (role.equals(b.getRole()) && b.getMembers().contains(member)) { b.getMembers().remove(member); break; } } // Set the new IAM Policy. Policy newIamPolicy = kms.projects().locations() .keyRings() .setIamPolicy(cryptoKey, new SetIamPolicyRequest().setPolicy(iamPolicy)) .execute(); System.out.println("Response: " + newIamPolicy); return newIamPolicy; } // [END kms_remove_member_from_keyring_policy] /** * Prints all the keyrings in the given project. */ public static void listKeyRings(String projectId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String keyRingPath = String.format( "projects/%s/locations/%s", projectId, location); // Make the RPC call ListKeyRingsResponse response = kms.projects().locations() .keyRings() .list(keyRingPath) .execute(); // Print the returned key rings if (null != response.getKeyRings()) { System.out.println("Key Rings: "); for (KeyRing keyRing : response.getKeyRings()) { System.out.println(keyRing.getName()); } } else { System.out.println("No keyrings defined."); } } /** * Prints all the keys in the given key ring. */ public static void listCryptoKeys(String projectId, String ringId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String keyRingPath = String.format( "projects/%s/locations/%s/keyRings/%s", projectId, location, ringId); ListCryptoKeysResponse cryptoKeys = kms.projects().locations().keyRings() .cryptoKeys() .list(keyRingPath) .execute(); for (CryptoKey key : cryptoKeys.getCryptoKeys()) { System.out.println(key); } } /** * Prints all the versions for the given crypto key. */ public static void listCryptoKeyVersions( String projectId, String ringId, String keyId) throws IOException { String location = "global"; // Create the Cloud KMS client. CloudKMS kms = createAuthorizedClient(); // The resource name of the cryptoKey String cryptoKeys = String.format( "projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s", projectId, location, ringId, keyId); DestroyCryptoKeyVersionRequest destroyRequest = new DestroyCryptoKeyVersionRequest(); ListCryptoKeyVersionsResponse versions = kms.projects().locations().keyRings().cryptoKeys() .cryptoKeyVersions() .list(cryptoKeys) .execute(); for (CryptoKeyVersion version : versions.getCryptoKeyVersions()) { System.out.println(version); } } public static void main(String[] args) throws IOException, CmdLineException { SnippetCommands commands = new SnippetCommands(); CmdLineParser parser = new CmdLineParser(commands); try { parser.parseArgument(args); } catch (CmdLineException e) { System.out.println(e); System.out.println(); e.getParser().printUsage(System.err); System.exit(1); } commands.command.run(); } }