This is an automated email from the ASF dual-hosted git repository.

AlinsRan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new 1f16a6c88 fix: fetch secrets from upstream ssl config (#13062)
1f16a6c88 is described below

commit 1f16a6c88fc280998b34f4c6f4c4fad7de136d33
Author: J.A. <[email protected]>
AuthorDate: Fri Jul 10 08:42:42 2026 +0200

    fix: fetch secrets from upstream ssl config (#13062)
---
 apisix/cli/file.lua                  |   2 +-
 apisix/init.lua                      |   7 +
 apisix/ssl.lua                       |   8 +-
 apisix/ssl/router/radixtree_sni.lua  |   8 +-
 docs/en/latest/terminology/secret.md |   4 +-
 docs/zh/latest/terminology/secret.md |   4 +-
 t/node/client-mtls.t                 | 252 ++++++++++++++++++++++++++++++++---
 t/node/upstream-mtls.t               | 242 +++++++++++++++++++++++++++++----
 8 files changed, 467 insertions(+), 60 deletions(-)

diff --git a/apisix/cli/file.lua b/apisix/cli/file.lua
index bbdb738e3..3944efbe3 100644
--- a/apisix/cli/file.lua
+++ b/apisix/cli/file.lua
@@ -342,7 +342,7 @@ function _M.read_yaml_conf(apisix_home)
             -- Therefore we need to check the absolute version instead
             local cert_path = 
pl_path.abspath(apisix_ssl.ssl_trusted_certificate)
             if not pl_path.exists(cert_path) then
-                util.die("certificate path", cert_path, "doesn't exist\n")
+                util.die("certificate path ", cert_path, " doesn't exist\n")
             end
             apisix_ssl.ssl_trusted_certificate = cert_path
         end
diff --git a/apisix/init.lua b/apisix/init.lua
index ece57e880..162affd3a 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -564,6 +564,13 @@ local function resolve_upstream_client_cert(api_ctx)
 
     core.log.info("matched upstream client ssl object, id: ", cert_id,
                   ", type: ", upstream_ssl.type)
+
+    -- avoid the per-request deepcopy done by fetch_secrets when the ssl object
+    -- holds plain cert/key
+    if apisix_secret.has_secret_ref(upstream_ssl) then
+        upstream_ssl = apisix_secret.fetch_secrets(upstream_ssl, true) or 
upstream_ssl
+    end
+
     api_ctx.upstream_ssl = upstream_ssl
     return true
 end
diff --git a/apisix/ssl.lua b/apisix/ssl.lua
index 9d0401fa2..f8a1b2e8a 100644
--- a/apisix/ssl.lua
+++ b/apisix/ssl.lua
@@ -214,9 +214,11 @@ function _M.check_ssl_conf(in_dp, conf)
             return nil, "client tls verify unsupported"
         end
 
-        local ok, err = validate(conf.client.ca, nil)
-        if not ok then
-            return nil, "failed to validate client_cert: " .. err
+        if not secret.check_secret_uri(conf.client.ca) then
+            local ok, err = validate(conf.client.ca, nil)
+            if not ok then
+                return nil, "failed to validate client_cert: " .. err
+            end
         end
     end
 
diff --git a/apisix/ssl/router/radixtree_sni.lua 
b/apisix/ssl/router/radixtree_sni.lua
index 07ad262ba..95e39c0ec 100644
--- a/apisix/ssl/router/radixtree_sni.lua
+++ b/apisix/ssl/router/radixtree_sni.lua
@@ -251,9 +251,9 @@ function _M.set(matched_ssl, sni)
         return false, err
     end
 
-    if matched_ssl.value.client then
-        local ca_cert = matched_ssl.value.client.ca
-        local depth = matched_ssl.value.client.depth
+    if new_ssl_value.client then
+        local ca_cert = new_ssl_value.client.ca
+        local depth = new_ssl_value.client.depth
         if apisix_ssl.support_client_verification() then
             local parsed_cert, err = apisix_ssl.fetch_cert(sni, ca_cert)
             if not parsed_cert then
@@ -262,7 +262,7 @@ function _M.set(matched_ssl, sni)
 
             local reject_in_handshake =
                 (ngx.config.subsystem == "stream") or
-                (matched_ssl.value.client.skip_mtls_uri_regex == nil)
+                (new_ssl_value.client.skip_mtls_uri_regex == nil)
             -- TODO: support passing `trusted_certs` (3rd arg, keep it nil for 
now)
             local ok, err = ngx_ssl.verify_client(parsed_cert, depth, nil,
                 reject_in_handshake)
diff --git a/docs/en/latest/terminology/secret.md 
b/docs/en/latest/terminology/secret.md
index ee5ba1260..ec713a661 100644
--- a/docs/en/latest/terminology/secret.md
+++ b/docs/en/latest/terminology/secret.md
@@ -23,10 +23,10 @@ title: Secret
 
 ## Description
 
-Secrets refer to any sensitive information required during the running process 
of APISIX, which may be part of the core configuration (such as the etcd's 
password) or some sensitive information in the plugin. Common types of Secrets 
in APISIX include:
+Secrets refer to any sensitive information required during the running process 
of APISIX, which may be part of the core configuration (such as the etcd's 
password), cryptographic material or some sensitive information in the plugin. 
Common types of Secrets in APISIX include:
 
 - username, the password for some components (etcd, Redis, Kafka, etc.)
-- the private key of the certificate
+- the public certificate, private key and ca certificates
 - API key
 - Sensitive plugin configuration fields, typically used for authentication, 
hashing, signing, or encryption
 
diff --git a/docs/zh/latest/terminology/secret.md 
b/docs/zh/latest/terminology/secret.md
index fc1cedf50..9384a54b1 100644
--- a/docs/zh/latest/terminology/secret.md
+++ b/docs/zh/latest/terminology/secret.md
@@ -23,10 +23,10 @@ title: Secret
 
 ## 描述
 
-密钥是指 APISIX 运行过程中所需的任何敏感信息,它可能是核心配置的一部分(如 etcd 的密码),也可能是插件中的一些敏感信息。APISIX 
中常见的密钥类型包括:
+密钥是指 APISIX 运行过程中所需的任何敏感信息,它可能是核心配置的一部分(如 etcd 的密码)、加密材料,也可能是插件中的一些敏感信息。APISIX 
中常见的密钥类型包括:
 
 - 一些组件(etcd、Redis、Kafka 等)的用户名、密码
-- 证书的私钥
+- 公钥证书、私钥和 CA 证书
 - API 密钥
 - 敏感的插件配置字段,通常用于身份验证、hash、签名或加密
 
diff --git a/t/node/client-mtls.t b/t/node/client-mtls.t
index 78715b98f..e59416960 100644
--- a/t/node/client-mtls.t
+++ b/t/node/client-mtls.t
@@ -22,6 +22,21 @@ BEGIN {
         $ENV{TEST_NGINX_USE_HUP} = 1;
         undef $ENV{TEST_NGINX_USE_STAP};
     }
+
+    sub set_env_from_file {
+        my ($env_name, $file_path) = @_;
+
+        open my $fh, '<', $file_path or die $!;
+        my $content = do { local $/; <$fh> };
+        close $fh;
+
+        $ENV{$env_name} = $content;
+    }
+
+    # set env
+    set_env_from_file('TEST_CERT', 't/certs/apisix.crt');
+    set_env_from_file('TEST_KEY', 't/certs/apisix.key');
+    set_env_from_file('MTLS_CA_CERT', 't/certs/mtls_ca.crt');
 }
 
 use t::APISIX;
@@ -48,7 +63,50 @@ run_tests();
 
 __DATA__
 
-=== TEST 1: bad client certificate
+=== TEST 1: store two certs and keys in vault
+--- exec
+VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/ssl 
\
+    test.com.crt=@t/certs/apisix.crt \
+    test.com.key=@t/certs/apisix.key \
+    mtls.client-ca.crt=@t/certs/mtls_ca.crt
+--- response_body
+Success! Data written to: kv/apisix/ssl
+
+
+
+=== TEST 2: set vault connection information
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/secrets/vault/test',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "http://0.0.0.0:8200";,
+                    "prefix": "kv/apisix",
+                    "token": "root"
+                }]],
+                [[{
+                    "key": "/apisix/secrets/vault/test",
+                    "value": {
+                        "uri": "http://0.0.0.0:8200";,
+                        "prefix": "kv/apisix",
+                        "token": "root"
+                    }
+                }]]
+                )
+            ngx.status = code
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 3: bad client certificate
 --- config
     location /t {
         content_by_lua_block {
@@ -83,7 +141,7 @@ GET /t
 
 
 
-=== TEST 2: missing client certificate
+=== TEST 4: missing client certificate
 --- config
     location /t {
         content_by_lua_block {
@@ -117,7 +175,7 @@ GET /t
 
 
 
-=== TEST 3: set verification
+=== TEST 5: set verification
 --- config
     location /t {
         content_by_lua_block {
@@ -195,7 +253,7 @@ GET /t
 
 
 
-=== TEST 4: hit
+=== TEST 6: hit
 --- request
 GET /mtls
 --- more_headers
@@ -205,7 +263,7 @@ hello world
 
 
 
-=== TEST 5: no client certificate
+=== TEST 7: no client certificate
 --- config
     location /t {
         content_by_lua_block {
@@ -245,7 +303,7 @@ GET /t
 
 
 
-=== TEST 6: hit
+=== TEST 8: hit
 --- request
 GET /mtls2
 --- more_headers
@@ -256,7 +314,7 @@ peer did not return a certificate
 
 
 
-=== TEST 7: wrong client certificate
+=== TEST 9: wrong client certificate
 --- config
     location /t {
         content_by_lua_block {
@@ -302,7 +360,7 @@ GET /t
 
 
 
-=== TEST 8: hit
+=== TEST 10: hit
 --- request
 GET /mtls3
 --- more_headers
@@ -313,7 +371,7 @@ certificate verify failed
 
 
 
-=== TEST 9: set verification
+=== TEST 11: set verification
 --- config
     location /t {
         content_by_lua_block {
@@ -357,7 +415,7 @@ GET /t
 
 
 
-=== TEST 10: hit with different host which doesn't require mTLS
+=== TEST 12: hit with different host which doesn't require mTLS
 --- exec
 curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://localhost:1994/hello -H "Host: x.com"
 --- response_body
@@ -365,7 +423,7 @@ hello world
 
 
 
-=== TEST 11: set verification (2 ssl objects)
+=== TEST 13: set verification (2 ssl objects)
 --- config
     location /t {
         content_by_lua_block {
@@ -428,7 +486,7 @@ GET /t
 
 
 
-=== TEST 12: hit without mTLS verify, with Host requires mTLS verification
+=== TEST 14: hit without mTLS verify, with Host requires mTLS verification
 --- exec
 curl -k https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
@@ -438,7 +496,7 @@ client certificate verified with SNI localhost, but the 
host is test.com
 
 
 
-=== TEST 13: set verification (2 ssl objects, both have mTLS)
+=== TEST 15: set verification (2 ssl objects, both have mTLS)
 --- config
     location /t {
         content_by_lua_block {
@@ -506,7 +564,7 @@ GET /t
 
 
 
-=== TEST 14: hit with mTLS verify, with Host requires different mTLS 
verification
+=== TEST 16: hit with mTLS verify, with Host requires different mTLS 
verification
 --- exec
 curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://localhost:1994/hello -H "Host: test.com"
 --- response_body eval
@@ -516,7 +574,7 @@ client certificate verified with SNI localhost, but the 
host is test.com
 
 
 
-=== TEST 15: request localhost and save tls session to reuse
+=== TEST 17: request localhost and save tls session to reuse
 --- max_size: 1048576
 --- exec
 echo "GET /hello HTTP/1.1\r\nHost: localhost\r\n" | \
@@ -528,7 +586,7 @@ qr/200 OK/
 
 
 
-=== TEST 16: request test.com with saved tls session
+=== TEST 18: request test.com with saved tls session
 --- max_size: 1048576
 --- exec
 echo "GET /hello HTTP/1.1\r\nHost: test.com\r\n" | \
@@ -541,7 +599,7 @@ sni in client hello mismatch hostname of ssl session, sni: 
test.com, hostname: l
 
 
 
-=== TEST 17: set verification (2 ssl objects, both have mTLS)
+=== TEST 19: set verification (2 ssl objects, both have mTLS)
 --- config
     location /t {
         content_by_lua_block {
@@ -612,7 +670,7 @@ GET /t
 
 
 
-=== TEST 18: skip the mtls, although no client cert provided
+=== TEST 20: skip the mtls, although no client cert provided
 --- exec
 curl -k https://localhost:1994/hello1
 --- response_body eval
@@ -620,7 +678,7 @@ qr/hello1 world/
 
 
 
-=== TEST 19: skip the mtls, although with wrong client cert
+=== TEST 21: skip the mtls, although with wrong client cert
 --- exec
 curl -k --cert t/certs/test2.crt --key t/certs/test2.key -k 
https://localhost:1994/hello1
 --- response_body eval
@@ -628,7 +686,7 @@ qr/hello1 world/
 
 
 
-=== TEST 20: mtls failed, returns 400
+=== TEST 22: mtls failed, returns 400
 --- exec
 curl -k https://localhost:1994/hello
 --- response_body eval
@@ -638,7 +696,7 @@ client certificate was not present
 
 
 
-=== TEST 21: mtls failed, wrong client cert
+=== TEST 23: mtls failed, wrong client cert
 --- exec
 curl --cert t/certs/test2.crt --key t/certs/test2.key -k 
https://localhost:1994/hello
 --- response_body eval
@@ -648,8 +706,158 @@ client certificate verification is not passed: FAILED
 
 
 
-=== TEST 22: mtls failed, at handshake phase
+=== TEST 24: mtls failed, at handshake phase
 --- exec
 curl -k -v --resolve "test.com:1994:127.0.0.1" https://test.com:1994/hello
 --- error_log
 peer did not return a certificate
+
+
+
+=== TEST 25: set ssl with cert, key and client ca in vault
+--- config
+    location /t {
+        content_by_lua_block {
+            local core = require("apisix.core")
+            local t = require("lib.test_admin")
+
+            -- TEST 19 left an ssl object on the same sni; remove it so that
+            -- the sni below resolves to exactly one ssl object
+            assert(t.test('/apisix/admin/ssls/2', ngx.HTTP_DELETE))
+
+            local data = {
+                snis = {"test.com"},
+                key =  "$secret://vault/test/ssl/test.com.key",
+                cert = "$secret://vault/test/ssl/test.com.crt",
+                client = {
+                    ca = "$secret://vault/test/ssl/mtls.client-ca.crt"
+                },
+            }
+
+            local code, body = t.test('/apisix/admin/ssls/1',
+                ngx.HTTP_PUT,
+                core.json.encode(data),
+                [[{
+                    "value": {
+                        "snis": ["test.com"],
+                        "key": "$secret://vault/test/ssl/test.com.key",
+                        "cert": "$secret://vault/test/ssl/test.com.crt",
+                        "client": {
+                            "ca": "$secret://vault/test/ssl/mtls.client-ca.crt"
+                        }
+                    },
+                    "key": "/apisix/ssls/1"
+                }]]
+              )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            local data = {
+                upstream = {
+                    type = "roundrobin",
+                    nodes = {
+                        ["127.0.0.1:1980"] = 1,
+                    },
+                },
+                uri = "/hello"
+            }
+            assert(t.test('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                core.json.encode(data)
+            ))
+
+            ngx.status = code
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 26: access to https with test.com
+--- exec
+curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://test.com:1994/hello
+--- response_body
+hello world
+--- error_log
+fetching data from secret uri
+
+
+
+=== TEST 27: set ssl with cert, key and client ca in env
+--- config
+    location /t {
+        content_by_lua_block {
+            local core = require("apisix.core")
+            local t = require("lib.test_admin")
+
+            local data = {
+                sni = "test.com",
+                key =  "$env://TEST_KEY",
+                cert = "$env://TEST_CERT",
+                client = {
+                    ca = "$env://MTLS_CA_CERT"
+                },
+            }
+
+            local code, body = t.test('/apisix/admin/ssls/1',
+                ngx.HTTP_PUT,
+                core.json.encode(data),
+                [[{
+                    "value": {
+                        "sni": "test.com",
+                        "key": "$env://TEST_KEY",
+                        "cert": "$env://TEST_CERT",
+                        "client": {
+                            "ca": "$env://MTLS_CA_CERT"
+                        }
+                    },
+                    "key": "/apisix/ssls/1"
+                }]]
+              )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            local data = {
+                upstream = {
+                    type = "roundrobin",
+                    nodes = {
+                        ["127.0.0.1:1980"] = 1,
+                    },
+                },
+                uri = "/hello"
+            }
+            assert(t.test('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                core.json.encode(data)
+            ))
+
+            ngx.status = code
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 28: access to https using client mtls
+--- exec
+curl --cert t/certs/mtls_client.crt --key t/certs/mtls_client.key -k 
https://test.com:1994/hello
+--- response_body
+hello world
+--- error_log
+fetching data from env uri
diff --git a/t/node/upstream-mtls.t b/t/node/upstream-mtls.t
index fc7ba8144..35b20e7a6 100644
--- a/t/node/upstream-mtls.t
+++ b/t/node/upstream-mtls.t
@@ -14,6 +14,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+
+BEGIN {
+    sub set_env_from_file {
+        my ($env_name, $file_path) = @_;
+
+        open my $fh, '<', $file_path or die $!;
+        my $content = do { local $/; <$fh> };
+        close $fh;
+
+        $ENV{$env_name} = $content;
+    }
+    # set env
+    set_env_from_file('MTLS_CERT_VAR', 't/certs/mtls_client.crt');
+    set_env_from_file('MTLS_KEY_VAR', 't/certs/mtls_client.key');
+}
+
 use t::APISIX;
 
 my $nginx_binary = $ENV{'TEST_NGINX_BINARY'} || 'nginx';
@@ -38,7 +54,49 @@ run_tests();
 
 __DATA__
 
-=== TEST 1: tls without key
+=== TEST 1: store cert and key in vault
+--- exec
+VAULT_TOKEN='root' VAULT_ADDR='http://0.0.0.0:8200' vault kv put kv/apisix/ssl 
\
+    mtls_client.crt=@t/certs/mtls_client.crt \
+    mtls_client.key=@t/certs/mtls_client.key
+--- response_body
+Success! Data written to: kv/apisix/ssl
+
+
+
+=== TEST 2: set vault connection information
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin").test
+            local code, body = t('/apisix/admin/secrets/vault/test',
+                ngx.HTTP_PUT,
+                [[{
+                    "uri": "http://0.0.0.0:8200";,
+                    "prefix": "kv/apisix",
+                    "token": "root"
+                }]],
+                [[{
+                    "key": "/apisix/secrets/vault/test",
+                    "value": {
+                        "uri": "http://0.0.0.0:8200";,
+                        "prefix": "kv/apisix",
+                        "token": "root"
+                    }
+                }]]
+                )
+            ngx.status = code
+            ngx.say(body)
+        }
+    }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 3: tls without key
 --- config
     location /t {
         content_by_lua_block {
@@ -77,7 +135,7 @@ GET /t
 
 
 
-=== TEST 2: tls with bad key
+=== TEST 4: tls with bad key
 --- config
     location /t {
         content_by_lua_block {
@@ -119,7 +177,7 @@ decrypt ssl key failed
 
 
 
-=== TEST 3: encrypt key by default
+=== TEST 5: encrypt key by default
 --- config
     location /t {
         content_by_lua_block {
@@ -248,7 +306,7 @@ false
 
 
 
-=== TEST 4: hit
+=== TEST 6: hit
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -259,7 +317,7 @@ hello world
 
 
 
-=== TEST 5: wrong cert
+=== TEST 7: wrong cert
 --- config
     location /t {
         content_by_lua_block {
@@ -300,7 +358,7 @@ passed
 
 
 
-=== TEST 6: hit
+=== TEST 8: hit
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -312,7 +370,7 @@ client SSL certificate verify error
 
 
 
-=== TEST 7: clean old data
+=== TEST 9: clean old data
 --- config
     location /t {
         content_by_lua_block {
@@ -333,7 +391,7 @@ GET /t
 
 
 
-=== TEST 8: don't encrypt key
+=== TEST 10: don't encrypt key
 --- yaml_config
 apisix:
     node_listen: 1984
@@ -467,7 +525,7 @@ true
 
 
 
-=== TEST 9: bind upstream
+=== TEST 11: bind upstream
 --- config
     location /t {
         content_by_lua_block {
@@ -494,7 +552,7 @@ GET /t
 
 
 
-=== TEST 10: hit
+=== TEST 12: hit
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -505,7 +563,7 @@ GET /server_port
 
 
 
-=== TEST 11: bind service
+=== TEST 13: bind service
 --- config
     location /t {
         content_by_lua_block {
@@ -532,7 +590,7 @@ GET /t
 
 
 
-=== TEST 12: hit
+=== TEST 14: hit
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -543,7 +601,7 @@ hello world
 
 
 
-=== TEST 13: get cert by tls.client_cert_id
+=== TEST 15: get cert by tls.client_cert_id
 --- config
     location /t {
         content_by_lua_block {
@@ -598,7 +656,7 @@ GET /t
 
 
 
-=== TEST 14: hit
+=== TEST 16: hit
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -609,7 +667,7 @@ hello world
 
 
 
-=== TEST 15: change ssl object type
+=== TEST 17: change ssl object type
 --- config
     location /t {
         content_by_lua_block {
@@ -640,7 +698,7 @@ GET /t
 
 
 
-=== TEST 16: hit, ssl object type mismatch
+=== TEST 18: hit, ssl object type mismatch
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -652,7 +710,7 @@ failed to get ssl cert: ssl type should be 'client'
 
 
 
-=== TEST 17: delete ssl object
+=== TEST 19: delete ssl object
 --- config
     location /t {
         content_by_lua_block {
@@ -673,7 +731,7 @@ GET /t
 
 
 
-=== TEST 18: hit, ssl object not exits
+=== TEST 20: hit, ssl object not exits
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
     ssl_verify_client on;
@@ -685,7 +743,7 @@ failed to get ssl cert: ssl id [1] not exits
 
 
 
-=== TEST 19: `tls.verify` only
+=== TEST 21: `tls.verify` only
 --- config
     location /t {
         content_by_lua_block {
@@ -723,7 +781,7 @@ passed
 
 
 
-=== TEST 20: hit
+=== TEST 22: hit
 When only `tls.verify` is present, the matching logic related to
 `client_cert`, `client_key` or `client_cert_id` should not be entered
 --- request
@@ -733,7 +791,7 @@ hello world
 
 
 
-=== TEST 21: set `verify` with `client_cert`, `client_key`
+=== TEST 23: set `verify` with `client_cert`, `client_key`
 --- config
     location /t {
         content_by_lua_block {
@@ -774,7 +832,7 @@ passed
 
 
 
-=== TEST 22: hit
+=== TEST 24: hit
 `tls.verify` does not affect the parsing of `client_cert`, `client_key`
 --- upstream_server_config
     ssl_client_certificate ../../certs/mtls_ca.crt;
@@ -786,7 +844,7 @@ hello world
 
 
 
-=== TEST 23: invalid cert (fetch_cert failure at runtime)
+=== TEST 25: invalid cert (fetch_cert failure at runtime)
 This test writes an invalid cert directly to etcd to bypass Admin API
 validation, and verifies that fetch_cert failure returns 503 at runtime.
 --- config
@@ -826,7 +884,7 @@ passed
 
 
 
-=== TEST 24: hit with invalid cert
+=== TEST 26: hit with invalid cert
 --- request
 GET /hello
 --- error_code: 503
@@ -836,7 +894,7 @@ PEM_read_bio_X509_AUX() failed
 
 
 
-=== TEST 25: invalid key (fetch_pkey failure at runtime)
+=== TEST 27: invalid key (fetch_pkey failure at runtime)
 This test writes a valid cert but an invalid key directly to etcd to bypass
 Admin API validation, and verifies that fetch_pkey failure returns 503 at 
runtime.
 --- config
@@ -876,10 +934,142 @@ passed
 
 
 
-=== TEST 26: hit with invalid key
+=== TEST 28: hit with invalid key
 --- request
 GET /hello
 --- error_code: 503
 --- error_log
 base64 decode ssl key failed
 --- wait_etcd_sync: 0.3
+
+
+
+=== TEST 29: get cert by tls.client_cert_id with $secret:// refs
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin")
+            local json = require("toolkit.json")
+
+            local data = {
+                type = "client",
+                cert = "$secret://vault/test/ssl/mtls_client.crt",
+                key = "$secret://vault/test/ssl/mtls_client.key"
+            }
+            local code, body = t.test('/apisix/admin/ssls/1',
+                ngx.HTTP_PUT,
+                json.encode(data)
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            local data = {
+                upstream = {
+                    scheme = "https",
+                    type = "roundrobin",
+                    nodes = {
+                        ["127.0.0.1:1983"] = 1,
+                    },
+                    tls = {
+                        client_cert_id = 1
+                    }
+                },
+                uri = "/hello"
+            }
+            local code, body = t.test('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                json.encode(data)
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+        }
+    }
+--- request
+GET /t
+
+
+
+=== TEST 30: hit
+--- upstream_server_config
+    ssl_client_certificate ../../certs/mtls_ca.crt;
+    ssl_verify_client on;
+--- request
+GET /hello
+--- response_body
+hello world
+--- error_log
+fetching data from secret uri
+
+
+
+=== TEST 31: get cert by tls.client_cert_id with $env:// refs
+--- config
+    location /t {
+        content_by_lua_block {
+            local t = require("lib.test_admin")
+            local json = require("toolkit.json")
+
+            local data = {
+                type = "client",
+                cert = "$env://MTLS_CERT_VAR",
+                key = "$env://MTLS_KEY_VAR"
+            }
+            local code, body = t.test('/apisix/admin/ssls/1',
+                ngx.HTTP_PUT,
+                json.encode(data)
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+
+            local data = {
+                upstream = {
+                    scheme = "https",
+                    type = "roundrobin",
+                    nodes = {
+                        ["127.0.0.1:1983"] = 1,
+                    },
+                    tls = {
+                        client_cert_id = 1
+                    }
+                },
+                uri = "/hello"
+            }
+            local code, body = t.test('/apisix/admin/routes/1',
+                ngx.HTTP_PUT,
+                json.encode(data)
+            )
+
+            if code >= 300 then
+                ngx.status = code
+                ngx.say(body)
+                return
+            end
+        }
+    }
+--- request
+GET /t
+
+
+
+=== TEST 32: hit
+--- upstream_server_config
+    ssl_client_certificate ../../certs/mtls_ca.crt;
+    ssl_verify_client on;
+--- request
+GET /hello
+--- response_body
+hello world
+--- error_log
+fetching data from env uri

Reply via email to