Skip to content

Instantly share code, notes, and snippets.

@jaydorsey
Created June 2, 2022 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jaydorsey/f3d29883cace99409513c5f4e86bd686 to your computer and use it in GitHub Desktop.
Save jaydorsey/f3d29883cace99409513c5f4e86bd686 to your computer and use it in GitHub Desktop.
Heroku secret inventory
# frozen_string_literal: true
# This script uses the platform-api gem to retrieve secrets from Heroku apps, pipelines, and test
# environments. This can be used to generate an inventory of all your secrets, so you can cross-reference
# it to determine if you had any pipeline/test secrets which were compromised as part of the recent
# Heroku breach
#
# I suggest importing these CSVs into a database, adding a couple metadata fields (compromised:boolean,
# notes:text, environment:string, status:string) and writing some SQL to come up with a list of secrets
# that were re-used across different environments
=begin
SELECT
id,
name,
environment,
status,
KEY,
old_value,
compromised,
notes
FROM
envs
WHERE
1 = 1
AND environment NOT in('test', 'pipeline')
-- just a list of statuses you could use for tracking
AND status NOT in('already rotated', 'not secret', 'not compromised', 'removed', 'not found')
AND old_value in( SELECT DISTINCT
(old_value)
FROM envs
WHERE (compromised = TRUE
OR status != 'not compromised')
AND environment in('test', 'pipeline'))
ORDER BY
KEY ASC, name ASC;
=end
require 'platform-api'
# Get a HEROKU_OAUTH_TOKEN from your Heroku account. Use a user that has admin access so they can see all the pipelines,
# applications, etc.
conn = PlatformAPI.connect_oauth(ENV.fetch('HEROKU_OAUTH_TOKEN'))
apps = conn.app.list
pipelines = conn.pipeline.list
f = File.open('apps.txt', 'w')
apps.each do |app|
name = app['name']
envs = conn.config_var.info_for_app(name)
environment = name.split('-').first
envs.each do |key, value|
f.write("#{name},#{environment},#{key},#{value}\n")
end
end
f.close
# List all the pipeline (review app) and test secrets that are configured for each pipeline
%w[review test].each do |type|
f = File.open("#{type}.txt", 'w')
pipelines.each do |pipeline|
name = pipeline['name']
envs = h.conn.pipeline_config_var.info_for_app(pipeline['id'], 'review')
envs.each do |key, value|
f.write("#{name},#{type},#{key},#{value}\n")
end
end
f.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment