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): vault secret without TTL configuration should not be refreshed #12877

Merged
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
message: Fixed a bug that allowed vault secrets to refresh even when they had no TTL set.
type: bugfix
scope: Core
18 changes: 17 additions & 1 deletion kong/pdk/vault.lua
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,23 @@ local function new(self)

else
lru_ttl = ttl
shdict_ttl = DAO_MAX_TTL
-- shared dict ttl controls when the secret
-- value will be refreshed by `rotate_secrets`
-- timer. If a secret whose remaining time is less
-- than `config.resurrect_ttl`(or DAO_MAX_TTL
-- if not configured), it could possibly
-- be updated in every cycle of `rotate_secrets`.
--
-- The shdict_ttl should be
-- `config.ttl` + `config.resurrect_ttl`
-- to make sure the secret value persists for
-- at least `config.ttl` seconds.
-- When `config.resurrect_ttl` is not set and
-- `config.ttl` is not set, shdict_ttl will be
-- DAO_MAX_TTL * 2; when `config.resurrect_ttl`
-- is not set but `config.ttl` is set, shdict_ttl
-- will be ttl + DAO_MAX_TTL
shdict_ttl = ttl + DAO_MAX_TTL
end

else
Expand Down
117 changes: 117 additions & 0 deletions spec/02-integration/13-vaults/05-ttl_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,123 @@ describe("vault ttl and rotation (#" .. strategy .. ") #" .. vault.name, functio
end)
end)

describe("vault rotation #without ttl (#" .. strategy .. ") #" .. vault.name, function()
local client
local secret = "my-secret"


local function http_get(path)
path = path or "/"

local res = client:get(path, {
headers = {
host = assert(vault.host),
},
})

assert.response(res).has.status(200)

return res
end


lazy_setup(function()
helpers.setenv("KONG_LUA_PATH_OVERRIDE", LUA_PATH)
helpers.setenv("KONG_VAULT_ROTATION_INTERVAL", "1")

vault:setup()

local bp = helpers.get_db_utils(strategy,
{ "vaults", "routes", "services", "plugins" },
{ "dummy" },
{ vault.name })


-- override a default config without default ttl
assert(bp.vaults:insert({
name = vault.name,
prefix = vault.prefix,
config = {
default_value = "init",
},
}))

local route = assert(bp.routes:insert({
name = vault.host,
hosts = { vault.host },
paths = { "/" },
service = assert(bp.services:insert()),
}))


-- used by the plugin config test case
assert(bp.plugins:insert({
name = "dummy",
config = {
resp_header_value = fmt("{vault://%s/%s}",
vault.prefix, secret),
},
route = { id = route.id },
}))

assert(helpers.start_kong({
database = strategy,
nginx_conf = "spec/fixtures/custom_nginx.template",
vaults = vault.name,
plugins = "dummy",
log_level = "info",
}, nil, nil, vault:fixtures() ))

client = helpers.proxy_client()
end)


lazy_teardown(function()
if client then
client:close()
end

helpers.stop_kong()
vault:teardown()

helpers.unsetenv("KONG_LUA_PATH_OVERRIDE")
end)


it("update secret value should not refresh cached vault reference(backend: #" .. vault.name .. ")", function()
local function check_plugin_secret(expect, ttl, leeway)
leeway = leeway or 0.25 -- 25%

local timeout = ttl + (ttl * leeway)

-- The secret value is supposed to be not refreshed
-- after several rotations
assert.has_error(function()
assert
.with_timeout(timeout)
.with_step(0.5)
.eventually(function()
local res = http_get("/")
local value = assert.response(res).has.header(DUMMY_HEADER)

if value == expect then
return true
end

return false
end)
.is_falsy("expected plugin secret not to be updated to '" .. expect .. "' "
.. "' within " .. tostring(timeout) .. "seconds")
end)
end

vault:update_secret(secret, "old")
check_plugin_secret("init", 5)

vault:update_secret(secret, "new")
check_plugin_secret("init", 5)
end)
end)

describe("#hybrid mode dp vault ttl and rotation (#" .. strategy .. ") #" .. vault.name, function()
local client
Expand Down
Loading