Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vault): remove no longer used vault references from secret rotation #13193

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions kong/db/dao/vaults.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
local constants = require "kong.constants"
local vault_loader = require "kong.db.schema.vault_loader"
local load_module_if_exists = require "kong.tools.module".load_module_if_exists
local is_vault_reference = require("kong.pdk.vault").is_reference
local list_concat = require("kong.tools.table").concat
local yield = require("kong.tools.yield").yield


local Vaults = {}
Expand All @@ -17,6 +20,8 @@ local log = ngx.log
local WARN = ngx.WARN
local DEBUG = ngx.DEBUG

local GLOBAL_QUERY_OPTS = { nulls = true, workspace = ngx.null }


local function load_vault_strategy(vault)
local ok, strategy = load_module_if_exists("kong.vaults." .. vault)
Expand Down Expand Up @@ -84,4 +89,53 @@ function Vaults:load_vault_schemas(vault_set)
end


local function find_vault_references(tab)
local refs = {}
for k, v in pairs(tab) do
local kt = type(k)
if kt == "table" then
refs = list_concat(refs, find_vault_references(k))

elseif kt == "string" and is_vault_reference(k) then
refs[#refs+1] = k
end

local vt = type(v)
if vt == "table" then
refs = list_concat(refs, find_vault_references(v))

elseif vt == "string" and is_vault_reference(v) then
refs[#refs+1] = v
end
end

return refs
end


function Vaults:find_references_in_entities()
local references = {}
local db = kong.db
for _, dao in pairs(db.daos) do
local schema = dao.schema
local name = schema.name
local page_size = db[name].pagination and db[name].pagination.max_page_size
for row, err in db[name]:each(page_size, GLOBAL_QUERY_OPTS) do
yield()
if not row then
kong.log.err(err)
return nil, err
end

-- references = list_concat(references, find_vault_references(row))
for _, ref in ipairs(find_vault_references(row)) do
references[ref] = true
end
end
end

return references
end


return Vaults
29 changes: 29 additions & 0 deletions kong/pdk/vault.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ local decode_json = cjson.decode

local NEGATIVELY_CACHED_VALUE = "\0"
local ROTATION_INTERVAL = tonumber(os.getenv("KONG_VAULT_ROTATION_INTERVAL"), 10) or 60
local UPDATE_WATCHLIST_INTERVAL = tonumber(os.getenv("KONG_VAULT_UPDATE_WATCHLIST_INTERVAL"), 10) or 3600
local DAO_MAX_TTL = constants.DATABASE.DAO_MAX_TTL


Expand Down Expand Up @@ -204,6 +205,7 @@ local function new(self)
local STRATEGIES = {}
local SCHEMAS = {}
local CONFIGS = {}
local SECRETS_WATCHLIST = {}

local BUNDLED_VAULTS = constants.BUNDLED_VAULTS
local VAULT_NAMES
Expand Down Expand Up @@ -1245,6 +1247,11 @@ local function new(self)
return nil, err
end

if not SECRETS_WATCHLIST[reference] then
SECRETS_CACHE:delete(old_cache_key)
return nil, fmt("remove reference %s from rotation due to not in the watchlist", reference)
end

local strategy, err, config, new_cache_key, parsed_reference, config_hash = get_strategy(reference)
if not strategy then
-- invalid cache keys are removed (e.g. a vault entity could have been removed)
Expand Down Expand Up @@ -1415,6 +1422,20 @@ local function new(self)
end


local function update_secrets_watchlist()
local vaults_dao = kong.db.vaults

local refs, err = vaults_dao:find_references_in_entities()
if not refs then
self.log.err("could not retrieve all vault references from database: ", err)
return
end

self.log.debug("updating vault secret watchlist with references")
SECRETS_WATCHLIST = refs
end


local initialized
---
-- Initializes vault.
Expand All @@ -1431,6 +1452,9 @@ local function new(self)

initialized = true

-- Update watchlist before starting secret rotation
update_secrets_watchlist()

if self.configuration.database ~= "off" then
self.worker_events.register(handle_vault_crud_event, "crud", "vaults")
end
Expand All @@ -1444,6 +1468,11 @@ local function new(self)
if err then
self.log.err("could not schedule timer to rotate vault secret references on init: ", err)
end

local _, err = self.timer:named_every("secret-watchlist-update", UPDATE_WATCHLIST_INTERVAL, update_secrets_watchlist)
if err then
self.log.err("could not schedule timer to update vault secret watchlist: ", err)
end
end


Expand Down
Loading