IBM Cloud Docs
Part 3: Send your notifications to a Slack channel

Part 3: Send your notifications to a Slack channel

This tutorial is part 3 of a 3-part tutorial series that guides you through setting up alerts for your expiring secrets.

In part 2 of this tutorial series, you learned how to create a GitHub issue from an event notification that originated in your IBM Cloud® Secrets Manager service instance. Part 3 shows you how to create another Cloud Functions action that uses an incoming Secrets Manager event to post a notification to Slack.

As of 31 May 2022, the Event Notifications service supports a built-in Slack integration! Instead of using a Cloud Functions action to forward your events to Slack, you can now select Slack as an Event Notifications destination. To learn more about this feature, check out the Event Notifications documentation.

The diagram shows the basic flow between the Secrets Manager, Event Notifications, and Cloud Functions that sends a notification to Slack.
Figure 1. Posting a notification to Slack

Before you begin

Be sure that you've completed Part 2: Enabling notifications for Secrets Manager. Before you get started with part 3, you also need the following prerequisites:

  • A Slack app with an incoming webhook URL enabled.

  • A Slack channel to post your incoming notifications.

    The Slack app must be added to your channel so that incoming messages are displayed. For more information, see the Slack documentation.

Create a Cloud Functions action

Similar to the Cloud Functions actionA code snippet that can be explicitly invoked, or run in response to an event. that you created in the previous tutorial, you can create another action that posts an incoming notification to Slack.

  1. In the IBM Cloud console, click the Menu icon Menu icon > Functions.

  2. In the navigation, click Actions > Create.

  3. Give the action a name. For example, sm-notifications-slack.

  4. Choose the default package.

  5. Select a Node.js runtime.

  6. Click Create.

  7. Obtain your new webhook URL.

    Now that you've created your action and obtained a new webhook URL, you can add it as an Event Notifications destination. Continue to the next step.

Update your Event Notifications settings

Next, update your Event Notifications settings so that the service can begin to forward any incoming events from Secrets Manager to your new Cloud Functions action.

  1. In the console, click the Menu icon Menu icon > Resource list.

  2. From the list of resources, select your Event Notifications instance.

  3. In the Event Notifications UI, go to Destinations.

  4. Create a destination so that your alerts can be forwarded to the Cloud Functions webhook that you created the previous step.

    1. From the navigation, click Destinations > Add.
    2. Provide a name for your destination. For example, Slack.
    3. Select Webhook as the destination type.
    4. Paste the URL that you copied from the Cloud Functions UI.
    5. From the list of HTTP verbs, select POST.
    6. Click Add.

    After you create your destination, copy your destination ID. You use this value to prepare your Functions code in a later step.

Create a subscription with webhook signing

Next, create a new Event Notifications subscription with webhook signing enabled.

With webhook signing, you verify that the notification payload is sent by Event Notifications and not by a third party. For more information, check out the Event Notifications documentation.

  1. Create a subscription with signing enabled between your existing Secrets Manager topic and your new Cloud Functions destination.

    1. In the Event Notifications UI, click Subscriptions > Create.
    2. Provide a name for your subscription. For example, Slack.
    3. Select the Secrets Manager topic that you created in part 1.
    4. Select the destination that you created in the previous step.
    5. In the Security section, select the Signing enabled option.
    6. Click Create.

    Now you're all set to securely deliver notifications to your webhook URL. Continue to the next step.

Prepare your sample code

Now you can prepare the sample code for your Cloud Functions action.

  1. Copy the following JavaScript code and update the placeholder values.

    const axios = require('axios');
    const jwtVerify = require('jsonwebtoken').verify;
    
    // Generate an IAM token
    async function getIAMToken() {
        const options = {
            url: 'https://iam.cloud.ibm.com/identity/token',
            method: 'POST',
            header: 'Content-Type: application/x-www-form-urlencoded',
            data: 'grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=API_KEY'
        };
    
        const response = await axios(options);
        const responseData = response.data;
        console.log("\nGenerated an IAM token..");
        return responseData.access_token;
    }
    
    // Get a public key to verify notifications
    async function getPublicKey() {
        const accessToken = await getIAMToken();
    
        const options = {
            method: 'GET',
            url: '<event_notifications_endpoint_url>/destinations/<destination_id>/public_key',
            headers: {
                'authorization': 'Bearer ' + accessToken
            }
        };
    
        const response = await axios(options);
        const responseData = response.data;
        console.log('\nRetrieved a public key from Event Notifications..');
        return responseData.public_key;
    }
    
    async function main(params) {
    
        try {
            const publicKey = await getPublicKey();
    
            // Verify the notification data using the retrieved public key
            const decodedNotification = await jwtVerify(params.__ow_body, publicKey).data.data;
            console.log(`\nDecoded an incoming event notification from Secrets Manager:\n${JSON.stringify(decodedNotification)}`);
    
            text = `Secrets Manager notification\n\`\`\`${JSON.stringify(decodedNotification)}\`\`\``;
    
            const article = { "text": text };
    
            // Post the decoded notification to Slack
            await axios.post('<slack_webhook_url>', article)
            console.log('\nNotification successfully forwarded to Slack!');
    
        } catch (error) {
            console.error(error);
        }
    }
    
    Table 1. Variables to replace in your Functions code
    Variable Description
    API_KEY An IBM Cloud API key with Manager access on the Event Notifications service.
    <event_notifications_endpoint_url> The base URL of your Event Notifications service instance. For more information, see the Event Notifications API documentation.
    <destination_id> The ID of the Event Notifications destination that you created in step 2.
    <slack_webhook_url> The incoming webhook URL that is associated with your Slack app. For example, https://hooks.slack.com/services/<id> For more information, see the Slack documentation.
  2. Paste the code into your Functions action.

    1. In the console, go Menu icon Menu icon > Functions > Actions to return to the Functions UI.
    2. From your list of actions, select the action that you created in step 1.
    3. Paste the code that you modified.
    4. Click Save.

Test your connection to Slack

Finally, verify that you're able to post your notifications to Slack. You can use the Settings > Event Notifications section in the Secrets Manager UI to send a test event.

The image shows the Event Notifications screen in the Secrets Manager UI.
Figure 2. Sending a test event to Event Notifications

  1. In the IBM Cloud console, go to your Secrets Manager instance.

  2. Go to Settings > Event Notifications, and click Send test event.

  3. Check the Slack channel that is associated with your webhook to verify the results.

    If the Functions action completed successfully, you receive a Slack message that is similar to the following example:

    Secrets Manager notification
    
    {"event_type":"test_event","secret_type":"test_secret_type","secrets":[{"event_time":"2022-03-09T21:14:32Z","secret_group_id":"default","secret_id":"27d3368f-bb4a-2792-a4b0-ee79a5383866","secret_name":"test_secret_name"}],"source_instance_api_public_url":"https://<instance_id>.<region>.secrets-manager.appdomain.cloud/api","source_instance_crn":"crn:v1:bluemix:public:secrets-manager:<region>:a/<account_id>:<instance_id>::","source_instance_dashboard_url":"https://cloud.ibm.com/services/secrets-manager/<your_service_dashboard_url>","source_service":"SecretsManager"}
    
  4. Optional. Check your Cloud Functions activations logs if you encounter issues.

    From the Cloud Functions activations dashboard, you can check to see your activated action. Notification successfully forwarded to Slack! is displayed in the response details if the code runs successfully.

    If you see HTTP 4XX errors in the logs, make sure that the API key in your action code has the correct level of access. For JWT signature errors, verify that the Event Notifications destination ID in the action code corresponds with your Cloud Functions webhook.

Conclusion

Great job! In this tutorial series, you learned how to:

  • Connect your Secrets Manager service instance to Event Notifications.
  • Create two Cloud Functions actions that forward your incoming notification content to GitHub and Slack.

From now on, a GitHub issue and Slack post are created each time that a certificate in your Secrets Manager service instance expires or is about to expire.