Slackmatic and Secrets

Visualize the flow of secrets in the Slackmatic Plugin to explore how plugins can authenticate with the APIs of commercial services.

strict digraph { rankdir=LR node [shape=box style=filled colorscheme=set312] subgraph cluster_clipboard { label=clipboard style=filled colorscheme=set312 fillcolor=5 copy_token [label="slack\ntoken"] } subgraph cluster_browser { label=browser style=filled colorscheme=set312 fillcolor=1 subgraph cluster_storage { label=localStorage style=filled colorscheme=set312 fillcolor=4 token [label="slack\ntoken"] } save [label="form save event" shape=cds fillcolor=12] drop [label="URL drop event" shape=cds fillcolor=12] } subgraph cluster_server { label=server style=filled colorscheme=set312 fillcolor=2 server_history [label="conversations.history"] } subgraph cluster_slack { label=slack style=filled colorscheme=set312 fillcolor=3 slack_history [label="conversations.history"] } copy_token -> save -> token token -> drop drop -> server_history [ label="slack\ntoken" ] server_history -> slack_history [ label="slack\ntoken" ] }

Author must copy the token from Slack webpages into some storage. Therefore, token must pass through the clipboard.

Token saved in localStorage is exposed to any javascript delivered to the browser from the wiki server's domain name.

Browser cannot talk to slack directly because of CORS restrictions. Therefore, the token must pass through the wiki server to get to slack.

strict digraph { rankdir=LR node [shape=box style=filled colorscheme=set312] subgraph cluster_clipboard { label=clipboard style=filled colorscheme=set312 fillcolor=5 copy_token [label="slack\ntoken"] } subgraph cluster_browser { label=browser style=filled colorscheme=set312 fillcolor=1 save [label="form save event" shape=cds fillcolor=12] drop [label="URL drop event" shape=cds fillcolor=12] } subgraph cluster_server { label=server style=filled colorscheme=set312 fillcolor=2 subgraph cluster_storage { label=disk style=filled colorscheme=set312 fillcolor=4 token [label="slack\ntoken"] } server_history [label="conversations.history"] } subgraph cluster_slack { label=slack style=filled colorscheme=set312 fillcolor=3 slack_history [label="conversations.history"] } copy_token -> save save -> token [label="slack\ntoken"] token -> server_history [constraint=none] drop -> server_history server_history -> slack_history [ label="slack\ntoken" ] }

Token saved in the server's disk is exposed to any code running on the server. This might be slightly easier to attack than browser's localStorage because you don't have to get your code moved from the server into the browser.

This has the advantage that the server could communicate with the external API unattended by the author. For example, we might ask the server to periodically refresh a cache of our colleagues' slack profiles.

strict digraph { rankdir=LR node [shape=box style=filled colorscheme=set312] subgraph cluster_clipboard { label=clipboard style=filled colorscheme=set312 fillcolor=5 copy_token [label="slack\ntoken"] } subgraph cluster_browser { label=browser style=filled colorscheme=set312 fillcolor=1 subgraph cluster_localstorage { label=localStorage style=filled colorscheme=set312 fillcolor=4 key [label="secret key"] } save [label="form save event" shape=cds fillcolor=12] drop [label="URL drop event" shape=cds fillcolor=12] } subgraph cluster_server { label=server style=filled colorscheme=set312 fillcolor=2 subgraph cluster_server_storage { label=disk style=filled colorscheme=set312 fillcolor=4 encyphered_token [label="encyphered\nslack token"] } server_history [label="conversations.history"] } subgraph cluster_slack { label=slack style=filled colorscheme=set312 fillcolor=3 slack_history [label="conversations.history"] } copy_token -> save key -> {save drop} [constraint=none] save -> encyphered_token [label="encyphered\nslack token"] encyphered_token -> server_history [constraint=none] drop -> server_history [label="secret key"] server_history -> slack_history [ label="slack\ntoken" ] }

Saving an encrypted token on the server makes it harder for code there to attack the token and thereby gain access to our slack data. The attacker must get code running in the browser to steal the secret key and share it with code running on the server that decrypts the token.

This has the disadvantage of preventing the server's unattended communication with the external API.

.

Paul suggested reading a couple resources around sharing secrets in aws lambda & serverless: aws serverless

YOUTUBE 7jSfJombUeY Seth Vargo, Better Kubernetes Secrets, Strange Loop 2019

- [ ] Draw another diagram with envelope encryption

strict digraph { rankdir=LR node [shape=box style=filled colorscheme=set312] subgraph cluster_clipboard { label=clipboard style=filled colorscheme=set312 fillcolor=5 copy_token [label="slack\ntoken"] } subgraph cluster_browser { label=browser style=filled colorscheme=set312 fillcolor=1 subgraph cluster_localstorage { label=localStorage style=filled colorscheme=set312 fillcolor=4 key [label="secret key"] } save [label="form save event" shape=cds fillcolor=12] drop [label="URL drop event" shape=cds fillcolor=12] } subgraph cluster_kms { label="key mgmt service" style=filled colorscheme=set312 fillcolor=3 kek [label="key encryption key"] } subgraph cluster_server { label=server style=filled colorscheme=set312 fillcolor=2 subgraph cluster_server_ram { label=RAM style=filled colorscheme=set312 fillcolor=4 kms_token [label="key mgmt\nservice token"] } subgraph cluster_server_storage { label=disk style=filled colorscheme=set312 fillcolor=4 encyphered_dek [label="encyphered\ndata encryption key"] encyphered_token [label="encyphered\nslack token"] } tick [label="scheduled event" shape=cds fillcolor=12 constraint=none] server_history [label="conversations.history"] } subgraph cluster_slack { label=slack style=filled colorscheme=set312 fillcolor=3 slack_history [label="conversations.history"] } tick -> kek [label=fetch] kek -> encyphered_dek [label=decrypt] encyphered_dek -> encyphered_token [label=decrypt constraint=none] copy_token -> save key -> {save drop} [constraint=none] save -> encyphered_token [label="encyphered\nslack token"] encyphered_token -> server_history [constraint=none] drop -> server_history [label="secret key"] server_history -> slack_history [ label="slack\ntoken" ] }

This tangled mess is not a good picture of envelope encryption. It was heading in that direction, but we think it's complicated enough to call for a sequence diagram instead of a graph.