IBM Cloud Docs
Apply end to end security to a cloud application

Apply end to end security to a cloud application

This tutorial may incur costs. Use the Cost Estimator to generate a cost estimate based on your projected usage.

This tutorial walks you through key security services available in the IBM Cloud® catalog and how to use them together. An application that provides file sharing will put security concepts into practice.

No application architecture is complete without a clear understanding of potential security risks and how to protect against such threats. Application data is a critical resource which can not be lost, compromised or stolen. Additionally, data should be protected at rest and in transit through encryption techniques. Encrypting data at rest protects information from disclosure even when it is lost or stolen. Encrypting data in transit (e.g. over the Internet) through methods such as HTTPS, SSL, and TLS prevents eavesdropping and so called man-in-the-middle attacks.

Authenticating and authorizing users' access to specific resources is another common requirement for many applications. Different authentication schemes may need to be supported: customers and suppliers using social identities, partners from cloud-hosted directories, and employees from an organization’s identity provider.

Objectives

  • Encrypt content in storage buckets with your own encryption keys.
  • Require users to authenticate before accessing an application.
  • Monitor and audit security-related API calls and other actions across cloud services.

The tutorial features a sample application that enables groups of users to upload files to a common storage pool and to provides access to those files via shareable links. The application is written in Node.js and deployed as a container to either IBM Cloud Kubernetes Service or Red Hat OpenShift on IBM Cloud. It leverages several security-related services and features to improve the application's security posture.

This tutorial will work with a cluster running in Classic Infrastructure or VPC Infrastructure.

Architecture
Architecture diagram of the tutorial

  1. User connects to the application.
  2. If using a custom domain and a TLS certificate, the certificate is managed by and deployed from Secrets Manager.
  3. App ID secures the application and redirects the user to the authentication page. Users can also sign up.
  4. The application runs in a Kubernetes cluster from an image stored in the Container Registry. This image is automatically scanned for vulnerabilities.
  5. Uploaded files are stored in Object Storage with accompanying metadata stored in IBM Cloudant.
  6. Object storage buckets, App ID, and Secrets Manager services leverage a user-provided key to encrypt data.
  7. Application management activities are logged by IBM Cloud Activity Tracker Event Routing and routed to IBM Cloud Logs for analysis.

Before you begin

This tutorial requires:

  • IBM Cloud CLI,
    • IBM Cloud Kubernetes Service plugin (kubernetes-service),
    • Container Registry plugin (container-registry),
  • kubectl to interact with Kubernetes clusters,
  • git to clone source code repository.

You will find instructions to download and install these tools for your operating environment in the Getting started with solution tutorials guide.

To avoid the installation of these tools you can use the Cloud Shell from the IBM Cloud console.

Create services

In the next section, you are going to create the services used by the application.

Decide where to deploy the application

The location and resource group of all resources that you create should match with the location and resource group of the Kubernetes cluster.

Capture user and application activities

The IBM Cloud Activity Tracker Event Routing must be configured to route auditing events to a IBM Cloud Logs target instance. Route audit events as described in configuring an IBM Logs target if not currently configured in your account.

At the end of this tutorial, you will review the events that were generated by completing the tutorial's steps.

Create a cluster for the application

IBM Cloud Kubernetes Service and Red Hat OpenShift on IBM Cloud provide environments to deploy highly available apps in containers that run in Kubernetes clusters.

Skip this section if you have an existing Kubernetes cluster you want to reuse with this tutorial, throughout the remainder of this tutorial the cluster name is referenced as secure-file-storage-cluster, simply substitute with the name of your cluster.

A minimal cluster with one (1) zone, one (1) worker node and the smallest available size (Flavor) is sufficient for this tutorial. To create your IBM Cloud Kubernetes Service cluster, follow the steps for either Creating VPC clusters or Creating classic clusters. To create your Red Hat OpenShift on IBM Cloud cluster, follow the steps for either Creating VPC clusters or Creating classic clusters.

Use your own encryption keys

Key Protect helps you provision encrypted keys for apps across IBM Cloud services. Key Protect and IBM Cloud Object Storage work together to protect your data at rest. In this section, you will create one root key for the storage bucket.

  1. Create an instance of Key Protect.
    1. Select a location.
    2. Set the name to secure-file-storage-kp.
    3. Select the resource group where to create the service instance and click Create.
  2. Under Keys, click the Add button to create a new root key. It will be used to encrypt the storage bucket and App ID data.
    1. Set the key type to Root key.
    2. Set the name to secure-file-storage-root-enckey.
    3. Then Add key.

Bring your own key (BYOK) by importing an existing root key.

Setup storage for user files

The file sharing application saves files to the Object Storage bucket. The relationship between files and users is stored as metadata in the IBM Cloudant database. In this section, you'll create and configure these services.

A bucket for the content

  1. Create an instance of Object Storage.
    1. Select a Standard plan and Set the name to secure-file-storage-cos.
    2. Use the same resource group as for the previous services and click Create.
  2. Under Service credentials, create a New credential.
    1. Set the name to secure-file-storage-cos-acckey.
    2. For Role select Writer.
    3. Under Advanced options, check Include HMAC Credential. This is required to generate pre-signed URLs.
    4. Click Add.
    5. Make note of the credentials. You will need them in a later step.
  3. Click Endpoints from the navigation sidebar:
    1. Set Resiliency to Regional and set the Location to the target location:
    2. For Classic infrastructure: Copy the Private service endpoint. It will be used later in the configuration of the application.
    3. For VPC infrastructure: Copy the Direct service endpoint. It will be used later in the configuration of the application.

Before creating the bucket, you will grant the Object Storage service instance access to the root key stored in the Key Protect service instance.

  1. Go to Manage > Access (IAM) > Authorizations in the IBM Cloud console.
  2. Click the Create button.
  3. In the Source service menu, select Cloud Object Storage.
  4. Switch to Resources based on selected attributes, check Source service instance and select the Object Storage service instance previously created.
  5. In the Target service menu, select Key Protect.
  6. Switch to Resources based on selected attributes, check Instance ID, select the Key Protect service instance created earlier.
  7. Enable the Reader role.
  8. Click the Authorize button.

Finally, create the bucket.

  1. Access the Object Storage service instance from the Resource List Under Storage.
  2. Click Create bucket and then Customize your bucket.
    1. Use a unique value for name, such as <your-initials>-secure-file-upload.
    2. Set Resiliency to Regional.
    3. Set Location to the same location where you created the Key Protect service instance.
    4. Set Storage class to Standard
  3. Under Service integrations (optional) / Encryption, enable Key management
    1. Select the Key Protect service instance created earlier by clicking on Use existing instance
    2. Select secure-file-storage-root-enckey as the key and click Associate key.
  4. Under Service integrations (optional) / Monitoring & Activity tracking, enable Activity tracking to have audit events persisted for analysis.
    1. After clicking the checkmark the service information for the Activity Tracker instance in the region should be shown.
    2. Now, enable Track Data events and select read & write as Data Events.
  5. Click Create bucket.

A database map relationships between users and their files

The IBM Cloudant database will contain metadata for all files uploaded from the application.

  1. Create an instance of IBM Cloudant service.
    1. Select Cloudant as the offering.
    2. Select a Multitenant environment and a region same as the previous services.
    3. Set the name to secure-file-storage-cloudant.
    4. Use the same resource group as for the previous services.
    5. Set Authentication method to IAM.
    6. Click Create.
  2. Back to the Resource List, locate the newly created service and click on it. Note: You will need to wait until the status changes to Active.
    1. Under Service credentials, create New credential.
    2. Set the name to secure-file-storage-cloudant-acckey.
    3. For Role select Manager.
    4. Keep the default values for the remaining fields.
    5. Click Add.
  3. Expand the newly created credentials and make note of the values. You will need them in a later step.
  4. Under Manage, click on Launch Dashboard.
  5. Click Create Database to create a Non-partitioned database named secure-file-storage-metadata.

Authenticate users

With App ID, you can secure resources and add authentication to your applications. As an alternative not used in this tutorial, App ID can integrate with Kubernetes Service to authenticate users accessing applications deployed in the cluster.

Before creating the App ID service, grant service access to Key Protect service. You must be the account owner or an administrator for the instance of Key Protect that you're working with. You must also have at least Viewer access for the App ID service.

  1. Go to Manage > Access IAM > Authorizations and click Create.
  2. Select the App ID service as your source service.
  3. Select Key Protect as your target service.
  4. Switch to Resources based on selected attributes, check Instance ID, select the Key Protect service instance created earlier.
  5. Assign the Reader role under Service access.
  6. Click Authorize to confirm the delegated authorization.

Now, Create an instance of the App ID service.

  1. Navigate to the App ID service creation page.

    1. Use the same location used for the previous services.
    2. Select the Graduated tier as plan.
    3. Set the Service name to secure-file-storage-appid.
    4. Select a resource group same as the previous services.
    5. Select the authorized Key Protect service name and the root key from the respective dropdowns.
    6. Click Create.
  2. Under Manage Authentication, in the Authentication Settings tab, add a web redirect URL pointing to the domain you will use for the application. The URL format is https://secure-file-storage.<Ingress subdomain>/redirect_uri. For example:

    • with the ingress subdomain: mycluster-1234-d123456789.us-south.containers.appdomain.cloud
    • the redirect URL is https://secure-file-storage.mycluster-1234-d123456789.us-south.containers.appdomain.cloud/redirect_uri.

    App ID requires the web redirect URL to be https or http. You can view your Ingress subdomain in the cluster dashboard or with ibmcloud ks cluster get --cluster <cluster-name>.

  3. In the same tab under Authentication Settings under Runtime Activity enable capturing events in IBM Cloud Activity Tracker Event Routing.

  4. Create service credentials:

    1. Under Service credentials, create New credential.
    2. Set the name to secure-file-storage-appid-acckey.
    3. For Role select Manager.
    4. Keep the default values for the remaining fields.
    5. Click Add.

You should customize the identity providers used as well as the login and user management experience in the App ID dashboard. This tutorial uses the defaults for simplicity. For a production environment, consider to use Multi-Factor Authentication (MFA) and advanced password rules.

Deploy the app

All services have been configured. In this section you will deploy the tutorial application to the cluster. All of this can be accomplished from a shell environment (terminal).

Get the code

  1. Get the application's code:
    git clone https://github.com/IBM-Cloud/secure-file-storage
    
  2. Go to the secure-file-storage/app directory:
    cd secure-file-storage/app
    

Fill in configuration settings and credentials

  1. If you are not logged in, use ibmcloud login or ibmcloud login --sso to log in interactively. Target your IBM Cloud region and resource group.

    ibmcloud target -r <region> -g <resource_group>
    

    You can find more CLI commands in the General IBM Cloud CLI (ibmcloud) commands topic in the documentation.

  2. Set the environment variables required for generating configuration files in the next step.

    1. Start by setting the cluster name by replacing <YOUR_CLUSTER_NAME>:
      export MYCLUSTER=<YOUR_CLUSTER_NAME>
      
    2. Set the ingress subdomain using ibmcloud ks commands:
      export INGRESS_SUBDOMAIN=$(ibmcloud ks cluster get --cluster $MYCLUSTER --output json | jq -r 'try(.ingressHostname) // .ingress.hostname')
      
    3. Set the ingress secret using ibmcloud ks commands:
      export INGRESS_SECRET=$(ibmcloud ks cluster get --cluster $MYCLUSTER --output json | jq -r 'try(.ingressSecretName) // .ingress.secretName')
      
    4. Set the image repository name to the pre-built image icr.io/solution-tutorials/tutorial-cloud-e2e-security:
      export IMAGE_REPOSITORY=icr.io/solution-tutorials/tutorial-cloud-e2e-security
      
    5. Set additional environment variables by replacing the default values:
      export BASENAME=secure-file-storage
      
    6. Set the namespace to use:
      export TARGET_NAMESPACE=default
      
    7. Optionally set $IMAGE_PULL_SECRET environment variable only if you are using another Kubernetes namespace than the default namespace and the IBM Cloud Container Registry for the image. This requires additional Kubernetes configuration (e.g. creating a container registry secret in the new namespace).
  3. Run the below command to generate secure-file-storage.yaml and secure-file-storage-ingress.yaml. It will use the environment variables you just configured together with the template files secure-file-storage.template.yaml and secure-file-storage-ingress.template.yaml.

    ./generate_yaml.sh
    

    As example, assuming the application is deployed to the default Kubernetes namespace:

    Environment variables used by the script
    Variable Value Description
    $IMAGE_PULL_SECRET Do not define when using provided image A secret to access the registry.
    $IMAGE_REPOSITORY icr.io/solution-tutorials/tutorial-cloud-e2e-security or icr.io/namespace/image-name The URL-like identifier for the built image based on the registry URL, namespace and image name from the previous section.
    $TARGET_NAMESPACE default the Kubernetes namespace where the app will be pushed.
    $INGRESS_SUBDOMAIN secure-file-stora-123456.us-south.containers.appdomain.cloud Retrieve from the cluster overview page or with ibmcloud ks cluster get --cluster <your-cluster-name>.
    $INGRESS_SECRET secure-file-stora-123456 Retrieve with ibmcloud ks cluster get --cluster <your-cluster-name>.
    $BASENAME secure-file-storage The prefix used to identify resources.
  4. Copy credentials.template.env to credentials.env:

    cp credentials.template.env credentials.env
    
  5. Edit credentials.env and fill in the blanks with these values:

    • the Object Storage service regional endpoint, the bucket name, the credentials created for the Object Storage service,
    • the credentials for secure-file-storage-cloudant,
    • and the credentials for App ID. The variable appid_redirect_uris is a comma-separated list of redirect URIs as discussed above.

    When using Cloud Shell, you can use nano credentials.env to edit the file.

Deploy to the cluster

  1. Gain access to your cluster as described in the instructions Connect via CLI accessible from the Actions... menu in your console overview page.
    ibmcloud ks cluster config --cluster $MYCLUSTER --admin
    
  2. Check that an Ingress secret is available in your target namespace. If not, you need to create it.
    ibmcloud ks ingress secret ls -c $MYCLUSTER
    
    If the Ingress secret has a CRN, use its name and CRN to create a secret in your target namespace:
    ibmcloud ks ingress secret create -c $MYCLUSTER -n $TARGET_NAMESPACE --cert-crn <crn-shown-in-the-output-above> --name <secret-name-shown-above>
    
    If the Ingress secret does not have a CRN, use the following command to recreate it in the target namespace:
    kubectl get secret $INGRESS_SECRET --namespace=ibm-cert-store -oyaml | grep -v '^\s*namespace:\s'| kubectl apply  --namespace=$TARGET_NAMESPACE -f -
    
  3. Create the secret used by the application to obtain service credentials:
    kubectl create secret generic secure-file-storage-credentials --from-env-file=credentials.env
    
  4. Deploy the app.
    kubectl apply -f secure-file-storage.yaml
    
  5. Deploy the network routing (a ClusterIP service and Ingress) for your app to make it accessible from the public internet.
    kubectl apply -f secure-file-storage-ingress.yaml
    

Test the application

The application can be accessed at https://secure-file-storage.<your-cluster-ingress-subdomain>/.

  1. Go to the application's home page. You will be redirected to the App ID default login page.
  2. Sign up for a new account with a valid email address.
  3. Wait for the email in your inbox to verify the account.
  4. Login.
  5. Choose a file to upload. Click Upload.
  6. Use the Share action on a file to generate a pre-signed URL that can be shared with others to access the file. The link is set to expire after 5 minutes.

Authenticated users have their own spaces to store files. While they can not see each other files, they can generate pre-signed URLs to grant temporary access to a specific file.

You can find more details about the application in the source code repository.

Review Security Events

Now that the application and its services have been successfully deployed, you can review the security events generated by that process. All the events are centrally available in IBM Cloud Logs instance.

  1. From the Observability dashboard, select the Cloud Logs tab and locate the IBM Cloud Logs instance that is receiving the auditing events and click Open dashboard.
  2. Review all logs sent to the service as you were provisioning and interacting with resources.

Optional: Use a custom domain and encrypt network traffic

By default, the application is accessible on a generic subdomain of containers.appdomain.cloud. However, it is also possible to use a custom domain with the deployed app. For continued support of https, access with encrypted network traffic, either a certificate for the desired hostname or a wildcard certificate needs to be provided. There are various combinations of services that can be used to manage DNS names and TLS certificates for integration into a Kubernetes application. This tutorial will use the following services:

  • DNS subdomain, secure-file-storage, of your own custom DNS domain, that is managed by IBM Cloud Internet Services (CIS) service. For the purpose of simplifying the steps in this tutorial, we will use example.com for the name of the custom DNS domain, make sure to substitute with your custom DNS domain in all steps.
  • Let's Encrypt to generate the TLS certificates.
  • IBM Cloud Secrets Manager to integrate with Let's Encrypt to generate the TLS certificate for secure-file-storage.example.com and securely store it.
  • Kubernetes External Secrets Operator to pull the secret TLS certificate directly from Secrets Manager

Instead of the following steps, you could also create a CNAME pointing to the app URI at your DNS provider, generate a TLS certificate and import its components into Secrets Manager.

Provision CIS and Secrets Manager instances

  • A IBM Cloud Internet Services instance is required. Use an existing instance or create one from this catalog entry. A number of pricing plans are available, including a free trial. The provisioning process of a new CIS will explain how to configure your existing DNS registrar (perhaps not in IBM Cloud) to use the CIS-provided domain name servers. Export the custom domain in the shell window:
    export MYDOMAIN=example.com
    
  • An instance of Secrets Manager is required. Use an existing instance or create a new one described in Creating a Secrets Manager service instance. If creating a new instance, name it secure-file-storage-sm. You can enhance the security of your secrets at rest by integrating with the Key Protect instance created earlier.

Create a DNS entry in the CIS instance using your Kubernetes cluster Ingress subdomain as the alias.

  1. Open the CIS service instance, you can find it in the Resource List.
  2. Click the Reliability tab on the left.
  3. Click the DNS tab on the top.
  4. Scroll down to the DNS Records section and click Add to create a new record:
    1. Type: CNAME
    2. Name: secure-file-storage
    3. Alias: The Ingress subdomain of your cluster. You can obtain the correct value in the shell by executing the following command:
      echo $INGRESS_SUBDOMAIN
      
    4. Click Add to add the new record.

Connect Secrets Manager instance to Let's Encrypt.

  1. A Let's Encrypt ACME account and associated .pem file is required. Use an existing one or create one:

    1. Install the acme-account-creation-tool. Creating a Let's Encrypt ACME account contains instructions and a link to the creation tool.
    2. Run acme-account-creation-tool to create an account specifically for this secure-file-storage example. Below is an example:
      $ ./acme-account-creation-tool-darwin-amd64 -e YOUREMAIL -o secure-file-storage.example.com -d letsencrypt-prod
      INFO[2022-12-28T13:30:00-08:00] Registering a new account with the CA
      INFO[2022-12-28T13:30:00-08:00] Account information written to file : secure-file-storage.example.com-account-info.json
      INFO[2022-12-28T13:30:00-08:00] Private key written to file : secure-file-storage.example.com-private-key.pem
      
      Account Info
      {
         "email": "YOUREMAIL",
         "registration_uri": "https://acme-v02.api.letsencrypt.org/acme/acct/891897087",
         "registration_body": {
            "status": "valid",
            "contact": [
               "mailto:YOUREMAIL"
            ]
         }
      }%
      $ ls
      secure-file-storage.example.com-account-info.json secure-file-storage.example.com-private-key.pem
      
  2. Connect the Let's Encrypt ACME account to the Secrets Manager instance. See Adding a certificate authority configuration in the UI for more details:

    1. Open the Secrets Manager service instance, you can find it in the Resource List.
    2. Open Secrets engines on the left and click Public certificates.
    3. Under Certificate authorities click Add.
    4. Name: LetsEncrypt and Certificate authority: Let's Encrypt.
    5. Under Select file click Add file and choose the secure-file-storage.example.com-private-key.pem or your existing .pem file from the chooser.
    6. Click Add.
  3. Connect the CIS as a DNS provider:

    1. Under DNS providers click Add.
    2. Name cis and choose Cloud Internet Services from the dropdown.
    3. Click Next.
    4. In the Authorization tab choose the CIS instance.
    5. Click Add.
  4. Order a certificate in Secrets Manager

    1. Open the Secrets Manager service and select Secrets on the left.
    2. Click Add.
    3. Click on Public certificate and then click on Next.
    4. Complete the form:
      • Name - type a name you can remember.
      • Description - enter a description of your choice.
      • Click on Next.
      • Under Certificate authority select your configured Let's Encrypt certificate authority engine.
      • Under Key algorithm, pick your preferred algorithm,
      • Bundle certificates - leave off
      • Automatic certificate rotation - leave off
      • Under DNS provider select your configured DNS provider instance
      • Click on Select domains check the Select with wildcard and leave the domain itself unchecked and click on Done.
    5. Click Next.
    6. Review your selections and click on Add.
    7. Click the three vertical dots menu for the active secret and choose Details and copy the CRN from the dialog. Export the value in the shell. It will look something like this:
      export PUBLIC_CERT_CRN=crn:v1:bluemix:public:secrets-manager:eu-de:a/abc123abc123abc123abc123:99999999-9999-9999-9999-999999999999:secret:aaaaaaaa-9999-9999-aaaa-123456781234
      
  5. This tutorial leverages service to service authorization to give the cluster access to the Secrets Manager service instance and its managed secrets.

    1. Go to the IAM Authorizations page and click Create to add a new authorization.
    2. Under Source select Kubernetes Service, then click to pick Specific resources. Then, for Source service instance, choose your cluster.
    3. Under Target select Secrets Manager, then, going with Specific resources and Instance ID, select your Secrets Manager service instance.
    4. Finally, under Roles select Manager and grant the authorization by clicking Authorize.
  6. Verify the values for MYDOMAIN and PUBLIC_CERT_CRN have been exported into the environment:

    echo MYDOMAIN $(printenv MYDOMAIN)
    echo PUBLIC_CERT_CRN $(printenv PUBLIC_CERT_CRN)
    
  7. Create an Ingress secret from the new TLS certificate.

    ibmcloud ks ingress secret create --name secure-file-storage-certificate --cluster $MYCLUSTER --cert-crn $PUBLIC_CERT_CRN --namespace $TARGET_NAMESPACE
    
  8. Run the below command to generate new copies of the configuration files. It will use all the environment variables you configured together with the template files secure-file-storage.template.yaml and secure-file-storage.template-ingress.yaml. You may want to first save the current version:

    cp secure-file-storage.yaml /tmp
    cp secure-file-storage-ingress.yaml /tmp
    
    ./generate_yaml.sh
    
  9. Apply the configuration changes to your cluster:

    kubectl apply -f secure-file-storage-ingress.yaml
    
  10. Switch back to the browser. In the IBM Cloud Resource List locate the previously created and configured App ID service and launch its management dashboard.

  • Click Manage Authentication on the left and the Authentication Settings tab on the top.
  • In the Add web redirect URLs form add https://secure-file-storage.example.com/redirect_uri as another URL.
  1. Everything should be in place now. Test the app by accessing it at your configured custom domain https://secure-file-storage.<your custom domain>.

Security: Rotate service credentials

To maintain security, service credentials, passwords and other keys should be replaced (rotated) a regular basis. Many security policies have a requirement to change passwords and credentials every 90 days or with similar frequency. Moreover, in the case an employee leaves the team or in (suspected) security incidents, access privileges should be changed immediately.

In this tutorial, services are utilized for different purposes, from storing files and metadata over securing application access to managing container images. Rotating the service credentials typically involves

  • renaming the existing service keys,
  • creating a new set of credentials with the previously used name,
  • replacing the access data in existing Kubernetes secrets and applying the changes,
  • and, after verification, deactivating the old credentials by deleting the old service keys.

Expand the tutorial

Security is never done. Try the below suggestions to enhance the security of your application.

Share resources

If you want to work with others on resources of this solution tutorial, you can share all or only some of the components. IBM Cloud Identity and Access Management (IAM) enables the authentication of users and service IDs and the access control to cloud resources. For granting access to a resource, you can assign predefined access roles to either a user, a service ID, or to an access group. An access group can be created to organize a set of users and service IDs into a single entity. It makes it easy for you to assign access. You can assign a single policy to the group instead of assigning the same access multiple times per individual user or service ID. Thus, you can organize groups for roles on your development project and align security and project management.

You can find information on the individual services and their available IAM access roles here:

To get started, check out the best practices for access management and how to define access groups.

Remove resources

To remove the resource, delete the deployed container and then the provisioned services.

If you share an account with other users, always make sure to delete only your own resources.

  1. Delete the deployed network configuration and the container:

    kubectl delete -f secure-file-storage-ingress.yaml
    

    Thereafter, run the following command:

    kubectl delete -f secure-file-storage.yaml
    
  2. Delete the secrets for the deployment:

    kubectl delete secret secure-file-storage-credentials
    
  3. If you utilized Secrets Manager, remove the related service to service authorization.

  4. In the IBM Cloud Resource List locate the resources that were created for this tutorial. Use the search box and secure-file-storage as pattern. Delete each of the services by clicking on the context menu next to each service and choosing Delete Service. Note that the Key Protect service can only be removed after the key has been deleted. Click on the service instance to get to the related dashboard and to delete the key.

Depending on the resource it might not be deleted immediately, but retained (by default for 7 days). You can reclaim the resource by deleting it permanently or restore it within the retention period. See this document on how to use resource reclamation.

Related content