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

change(jwt-auth): unify apisix/core/vault.lua and apisix/secret/vault.lua #8660

Merged
merged 15 commits into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from 14 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ A/B testing, canary release, blue-green deployment, limit rate, defense against
- [Elasticsearch](docs/en/latest/plugins/elasticsearch-logger.md): push logs to Elasticsearch.
- [Datadog](docs/en/latest/plugins/datadog.md): push custom metrics to the DogStatsD server, comes bundled with [Datadog agent](https://docs.datadoghq.com/agent/), over the UDP protocol. DogStatsD basically is an implementation of StatsD protocol which collects the custom metrics for Apache APISIX agent, aggregates it into a single data point and sends it to the configured Datadog server.
- [Helm charts](https://github.com/apache/apisix-helm-chart)
- [HashiCorp Vault](https://www.vaultproject.io/): Support secret management solution for accessing secrets from Vault secure storage backed in a low trust environment. Currently, RS256 keys (public-private key pairs) or secret keys can be linked from vault in [jwt-auth](docs/en/latest/plugins/jwt-auth.md#enable-jwt-auth-with-vault-compatibility) authentication plugin.
- [HashiCorp Vault](https://www.vaultproject.io/): Support secret management solution for accessing secrets from Vault secure storage backed in a low trust environment. Currently, RS256 keys (public-private key pairs) or secret keys can be linked from vault in jwt-auth authentication plugin using [APISIX Secret](docs/en/latest/terminology/secret.md) resource.

- **Highly scalable**
- [Custom plugins](docs/en/latest/plugin-develop.md): Allows hooking of common phases, such as `rewrite`, `access`, `header filter`, `body filter` and `log`, also allows to hook the `balancer` stage.
Expand Down
127 changes: 0 additions & 127 deletions apisix/core/vault.lua

This file was deleted.

74 changes: 9 additions & 65 deletions apisix/plugins/jwt-auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ local core = require("apisix.core")
local jwt = require("resty.jwt")
local consumer_mod = require("apisix.consumer")
local resty_random = require("resty.random")
local vault = require("apisix.core.vault")
local new_tab = require ("table.new")

local ngx_encode_base64 = ngx.encode_base64
Expand Down Expand Up @@ -71,10 +70,6 @@ local consumer_schema = {
type = "boolean",
default = false
},
vault = {
type = "object",
properties = {}
},
lifetime_grace_period = {
type = "integer",
minimum = 0,
Expand Down Expand Up @@ -102,19 +97,6 @@ local consumer_schema = {
},
required = {"public_key", "private_key"},
},
{
properties = {
vault = {
type = "object",
properties = {}
},
algorithm = {
enum = {"RS256", "ES256"},
},
},
required = {"vault"},
},

}
}
},
Expand Down Expand Up @@ -147,11 +129,6 @@ function _M.check_schema(conf, schema_type)
return false, err
end

if conf.vault then
core.log.info("skipping jwt-auth schema validation with vault")
return true
end

if conf.algorithm ~= "RS256" and conf.algorithm ~= "ES256" and not conf.secret then
conf.secret = ngx_encode_base64(resty_random.bytes(32, true))
elseif conf.base64_secret then
Expand All @@ -161,8 +138,8 @@ function _M.check_schema(conf, schema_type)
end

if conf.algorithm == "RS256" or conf.algorithm == "ES256" then
-- Possible options are a) both are in vault, b) both in schema
-- c) one in schema, another in vault.
-- Possible options are a) public key is missing
-- b) private key is missing
if not conf.public_key then
return false, "missing valid public key"
end
Expand Down Expand Up @@ -243,25 +220,8 @@ local function fetch_jwt_token(conf, ctx)
return val
end


local function get_vault_path(username)
return "consumer/".. username .. "/jwt-auth"
end


local function get_secret(conf, consumer_name)
local secret = conf.secret
if conf.vault then
local res, err = vault.get(get_vault_path(consumer_name))
if not res then
return nil, err
end

if not res.data or not res.data.secret then
return nil, "secret could not found in vault: " .. core.json.encode(res)
end
secret = res.data.secret
end

if conf.base64_secret then
return ngx_decode_base64(secret)
Expand All @@ -274,32 +234,16 @@ end
local function get_rsa_or_ecdsa_keypair(conf, consumer_name)
local public_key = conf.public_key
local private_key = conf.private_key
-- if keys are present in conf, no need to query vault (fallback)

if public_key and private_key then
return public_key, private_key
elseif public_key and not private_key then
return public_key, nil, "missing private key"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@shreemaan-abhishek shreemaan-abhishek Jan 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add a nil check there? I think we should. Even the previous implementation would return nil in some cases. Not sure why it is not being checked.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if not public_key then

Here we check if public_key is nil to detect the err.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not quite sure what you are trying to say, could you please elaborate? 😅

elseif not public_key and private_key then
return nil, private_key, "missing public key"
else
return nil, nil, "public and private keys are missing"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't remove the elseif statements so that a better error message could be returned. Let me know if this is not up to the mark.

end

local vout = {}
if conf.vault then
local res, err = vault.get(get_vault_path(consumer_name))
if not res then
return nil, nil, err
end

if not res.data then
return nil, nil, "key pairs could not found in vault: " .. core.json.encode(res)
end
vout = res.data
end

if not public_key and not vout.public_key then
return nil, nil, "missing public key, not found in config/vault"
end
if not private_key and not vout.private_key then
return nil, nil, "missing private key, not found in config/vault"
end

return public_key or vout.public_key, private_key or vout.private_key
end


Expand Down
6 changes: 0 additions & 6 deletions apisix/secret/vault.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ local _M = {
schema = schema
}

-- This code is copied from apisix/core/vault.lua.
-- The functions in apisix/core/vault.lua are currently only used in the jwt-auth plugin,
-- and it is not suitable to be placed in the core module of APISIX.
--
-- When KMS is fully functional, we will remove apisix/core/vault.lua.
--
local function make_request_to_vault(conf, method, key, data)
local httpc = http.new()
-- config timeout or default to 5000 ms
Expand Down
13 changes: 0 additions & 13 deletions conf/config-default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -250,19 +250,6 @@ nginx_config: # config for render the template to generate n
tars: 1m
cas-auth: 10m

# HashiCorp Vault storage backend for sensitive data retrieval. The config shows an example of what APISIX expects if you
# wish to integrate Vault for secret (sensetive string, public private keys etc.) retrieval. APISIX communicates with Vault
# server HTTP APIs. By default, APISIX doesn't need this configuration.
# vault:
# host: "http://0.0.0.0:8200" # The host address where the vault server is running.
# timeout: 10 # request timeout 30 seconds
# token: root # Authentication token to access Vault HTTP APIs
# prefix: kv/apisix # APISIX supports vault kv engine v1, where sensitive data are being stored
# and retrieved through vault HTTP APIs. enabling a prefix allows you to better enforcement of
# policies, generate limited scoped tokens and tightly control the data that can be accessed
# from APISIX.


#discovery: # service discovery center
# dns:
# servers:
Expand Down
2 changes: 1 addition & 1 deletion docs/en/latest/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ APISIX facilitates interface traffic handling for websites, mobile and IoT appli
- Multi-platform support: APISIX can run from bare-metal machines to Kubernetes providing a vendor neutral, multi-platform solution. It also provides integration to cloud services like AWS Lambda, Azure Function, Lua functions and Apache OpenWhisk.
- Fully dynamic: APISIX supports hot-reloading, meaning you don't need to restart the service to reflect changes in the configuration.
- Fine-grained routing: APISIX supports using all [built-in NGINX variables](http://nginx.org/en/docs/varindex.html) for routing. You can define custom matching functions to filter requests and match Route.
- Ops-friendly: APISIX is renowned for its ops-friendliness by DevOps teams. It integrates with tools and platforms like [HashiCorp Vault](./plugins/jwt-auth.md#usage-with-hashicorp-vault), [Zipkin](./plugins/zipkin.md), [Apache SkyWalking](./plugins/skywalking.md), [Consul](./discovery/consul_kv.md), [Nacos](./discovery/nacos.md) and [Eureka](./discovery.md). With [APISIX Dashboard](https://github.com/apache/apisix-dashboard), operators can configure APISIX through an easy-to-use and intuitive UI.
- Ops-friendly: APISIX is renowned for its ops-friendliness by DevOps teams. It integrates with tools and platforms like [HashiCorp Vault](./terminology/secret.md#use-vault-to-manage-secrets), [Zipkin](./plugins/zipkin.md), [Apache SkyWalking](./plugins/skywalking.md), [Consul](./discovery/consul_kv.md), [Nacos](./discovery/nacos.md) and [Eureka](./discovery.md). With [APISIX Dashboard](https://github.com/apache/apisix-dashboard), operators can configure APISIX through an easy-to-use and intuitive UI.
- Multi-language Plugin support: APISIX supports multiple programming languages for Plugin development. Developers can choose a language-specific SDK to write custom Plugins.

## Key concepts
Expand Down
Loading