This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git
The following commit(s) were added to refs/heads/master by this push:
new eec76bacbc Add TLS support for OAP HTTP/REST servers with cert
hot-reload (#13933)
eec76bacbc is described below
commit eec76bacbc029e5b9974099cc0d9693841222d56
Author: kezhenxu94 <[email protected]>
AuthorDate: Tue Jun 30 22:11:37 2026 +0800
Add TLS support for OAP HTTP/REST servers with cert hot-reload (#13933)
The gRPC servers already supported TLS, mTLS, and cert reload on rotation.
This adds the equivalent for the Armeria-based HTTP/REST servers (core REST
/
GraphQL, sharing REST, admin, PromQL, LogQL, TraceQL, Zipkin
query/receiver):
- HTTPServer now reloads the key pair from disk via Armeria
TlsProvider.ofScheduled, so rotated certificates (e.g. a refreshed
Kubernetes
secret) are picked up without restarting the OAP. Previously the cert/key
were
read once at startup.
- Every HTTP server exposes the same restSSLEnabled / restSSLKeyPath /
restSSLCertChainPath config structure, each with its own dedicated
environment
variables: SW_CORE_REST_SSL_*, SW_RECEIVER_SHARING_REST_SSL_*,
SW_ADMIN_SERVER_REST_SSL_*, SW_PROMQL_REST_SSL_*, SW_LOGQL_REST_SSL_*,
SW_TRACEQL_REST_SSL_*, SW_QUERY_ZIPKIN_REST_SSL_*,
SW_RECEIVER_ZIPKIN_REST_SSL_*.
Each server reads the settings from its own module config.
- HTTP TLS is server-side only (no mTLS).
Adds HTTPServerTLSTest covering disk load, rotation pickup, and missing
files;
updates application.yml and the TLS / configuration-vocabulary / changelog
docs.
---
docs/en/changes/changes.md | 10 +++
docs/en/setup/backend/configuration-vocabulary.md | 21 ++++++
docs/en/setup/backend/grpc-security.md | 35 +++++++++
.../server/module/AdminServerModuleConfig.java | 9 +++
.../server/module/AdminServerModuleProvider.java | 3 +
.../oap/server/core/CoreModuleConfig.java | 9 +++
.../oap/server/core/CoreModuleProvider.java | 3 +
.../oap/server/library/server/http/HTTPServer.java | 38 ++++++++--
.../library/server/http/HTTPServerTLSTest.java | 82 ++++++++++++++++++++++
.../skywalking/oap/query/logql/LogQLConfig.java | 7 ++
.../skywalking/oap/query/logql/LogQLProvider.java | 3 +
.../skywalking/oap/query/promql/PromQLConfig.java | 7 ++
.../oap/query/promql/PromQLProvider.java | 3 +
.../oap/query/traceql/TraceQLConfig.java | 7 ++
.../oap/query/traceql/TraceQLProvider.java | 3 +
.../oap/query/zipkin/ZipkinQueryConfig.java | 7 ++
.../oap/query/zipkin/ZipkinQueryProvider.java | 3 +
.../sharing/server/SharingServerConfig.java | 8 +++
.../server/SharingServerModuleProvider.java | 6 +-
.../receiver/zipkin/ZipkinReceiverConfig.java | 7 ++
.../receiver/zipkin/ZipkinReceiverProvider.java | 3 +
.../src/main/resources/application.yml | 29 ++++++++
test/e2e-v2/cases/storage/expected/config-dump.yml | 15 ++++
23 files changed, 311 insertions(+), 7 deletions(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 86a0094398..a766359d48 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -5,6 +5,16 @@
* Extend the `GET /inspect/entities` admin API to inspect a metric persisted
by **any** OAP, even one this node does not define locally. When the metric is
unknown to the local registry, the caller supplies `valueColumn` + `valueType`
and the storage backend resolves the physical index/table/group from its own
running config (no DB schema/table-metadata read): ES uses the merged
`metrics-all` index + `metric_table` discriminator, JDBC probes the node's
function tables by the `table_name` [...]
* Add the `POST /inspect/values` admin API — read the value series of a metric
persisted by **another** OAP (one this node does not define locally) by
supplying its `{valueColumn, valueType}`. The real MQE engine runs over a
request-scoped `InspectQueryContext` overlay (provide-if-absent — the local
catalog always wins) that makes the foreign metric look registered to every
read path: `ValueColumnMetadata` resolves its value column / type / scope, and
the storage location registries reso [...]
* Remove the always-on alarm-to-event conversion (`EventHookCallback`). A
triggered alarm is no longer synthesized into the events pipeline as an
`Alarm`/`AlarmRecovery` event; events now originate only from real event
sources (agents, SkyWalking CLI, Kubernetes Event Exporter). Alarms remain
available through the alarm store (`getAlarm`/`queryAlarms`) and the configured
alarm hooks. This drops a documented "Known Event" and removes 1-2 synthetic
event records per alarm fire.
+* **TLS for all OAP HTTP/REST servers, with cert hot-reload.** Adds the
+ `restSSLEnabled` / `restSSLKeyPath` / `restSSLCertChainPath` config
structure to every
+ OAP HTTP server — core REST, sharing-server, admin, PromQL, LogQL, TraceQL
and Zipkin
+ query/receiver — each with its own dedicated environment variables
(`SW_CORE_REST_SSL_*`,
+ `SW_RECEIVER_SHARING_REST_SSL_*`, `SW_ADMIN_SERVER_REST_SSL_*`,
`SW_PROMQL_REST_SSL_*`,
+ `SW_LOGQL_REST_SSL_*`, `SW_TRACEQL_REST_SSL_*`, `SW_QUERY_ZIPKIN_REST_SSL_*`,
+ `SW_RECEIVER_ZIPKIN_REST_SSL_*`). The shared Armeria `HTTPServer` reloads
the key pair
+ from disk on rotation (via `TlsProvider.ofScheduled`) so refreshed
certificates are
+ picked up without restarting the OAP, matching the existing gRPC SSL
hot-reload
+ behavior. HTTP TLS is server-side only (no mTLS).
* **New `queryAlarms` GraphQL query — entity / layer / rule filters for
alarms.** Adds
a comprehensive alarm query API alongside the legacy `getAlarm`. The new
`queryAlarms(condition: AlarmQueryCondition!): Alarms` accepts a single
input type
diff --git a/docs/en/setup/backend/configuration-vocabulary.md
b/docs/en/setup/backend/configuration-vocabulary.md
index 46f7f8f31c..51fbd712df 100644
--- a/docs/en/setup/backend/configuration-vocabulary.md
+++ b/docs/en/setup/backend/configuration-vocabulary.md
@@ -14,6 +14,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPath
| Web context path of
RESTful services.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| ServerSocketChannel
Backlog of RESTful services.
[...]
+| - | - | restSSLEnabled
| Activates TLS for the
core REST (GraphQL query) HTTP server. Every OAP HTTP server exposes the same
`restSSL*` structure with its own dedicated env vars; the cert/key are reloaded
on rotation without a restart. Server-side TLS only (no mTLS).
[...]
+| - | - | restSSLKeyPath
| File path of the
HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER).
[...]
+| - | - | restSSLCertChainPath
| File path of the
HTTP/REST SSL X.509 certificate chain.
[...]
| - | - | httpMaxRequestHeaderSize
| Maximum request header
size accepted.
[...]
| - | - | gRPCHost
| Binding IP of gRPC
services, including gRPC data report and internal communication among OAP
nodes.
[...]
| - | - | gRPCPort
| Binding port of gRPC
services.
[...]
@@ -153,6 +156,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPath
| Web context path of
RESTful services.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| ServerSocketChannel
backlog of RESTful services.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the sharing REST HTTP server (reloaded on rotation; server-side TLS
only). | SW_RECEIVER_SHARING_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_RECEIVER_SHARING_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_RECEIVER_SHARING_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | httpMaxRequestHeaderSize
| Maximum request header
size accepted.
[...]
| - | - | gRPCHost
| Binding IP of gRPC
services. Services include gRPC data report and internal communication among
OAP nodes.
[...]
| - | - | gRPCPort
| Binding port of gRPC
services.
[...]
@@ -206,6 +212,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPath
| Web context path of
RESTful services.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| Maximum request header
size accepted.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the Zipkin receiver HTTP server (reloaded on rotation; server-side TLS
only). | SW_RECEIVER_ZIPKIN_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_RECEIVER_ZIPKIN_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_RECEIVER_ZIPKIN_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | enableKafkaCollector
| Enable Kafka Collector.
[...]
| - | - | kafkaBootstrapServers
| Kafka
ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG.
[...]
| - | - | kafkaGroupId
| Kafka
ConsumerConfig.GROUP_ID_CONFIG.
[...]
@@ -253,6 +262,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPath
| Web context path of
RESTful services.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| Maximum request header
size accepted.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the Zipkin query HTTP server (reloaded on rotation; server-side TLS
only). | SW_QUERY_ZIPKIN_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_QUERY_ZIPKIN_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_QUERY_ZIPKIN_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | lookback
| Default look back for
traces and autocompleteTags, 1 day in millis
[...]
| - | - | namesMaxAge
| The Cache-Control
max-age (seconds) for serviceNames, remoteServiceNames and spanNames
[...]
| - | - | uiQueryLimit
| Default traces query
max size
[...]
@@ -263,6 +275,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPath
| Web context path of
RESTful services.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| Maximum request header
size accepted.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the PromQL HTTP server (reloaded on rotation; server-side TLS only). |
SW_PROMQL_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_PROMQL_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_PROMQL_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | buildInfoVersion
| Mock version for API
buildInfo
[...]
| - | - | buildInfoRevision
| Mock revision for API
buildInfo
[...]
| - | - | buildInfoBranch
| Mock branch for API
buildInfo
[...]
@@ -278,6 +293,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | restContextPathSkywalking
| Web context path for
the SkyWalking native data source endpoint.
[...]
| - | - | restIdleTimeOut
| Connector idle timeout
of RESTful services (in milliseconds).
[...]
| - | - | restAcceptQueueSize
| ServerSocketChannel
Backlog of RESTful services.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the TraceQL HTTP server (reloaded on rotation; server-side TLS only). |
SW_TRACEQL_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_TRACEQL_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_TRACEQL_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | lookback
| If the query does not
provide a start time (default end time is current), this is the default
look-back duration for traces and autocomplete tag queries (in milliseconds).
[...]
| - | - | zipkinTracesListResultTags
| Span tag keys included
in the trace list result for the Zipkin data source. These tags are used for
trace grouping and shown in the trace list panel. Multiple values are separated
by commas.
[...]
| - | - | skywalkingTracesListResultTags
| Span tag keys included
in the trace list result for the SkyWalking native data source. These tags are
used for trace grouping and shown in the trace list panel. Multiple values are
separated by commas.
[...]
@@ -354,6 +372,9 @@ It divided into several modules, each of which has its own
settings. The followi
| - | - | contextPath
| Web context path of the
admin HTTP host.
[...]
| - | - | idleTimeOut
| Connector idle timeout
of the admin HTTP host (in milliseconds).
[...]
| - | - | acceptQueueSize
| ServerSocketChannel
backlog of the admin HTTP host.
[...]
+| - | - | restSSLEnabled | Activates
TLS for the admin HTTP server (reloaded on rotation; server-side TLS only). |
SW_ADMIN_SERVER_REST_SSL_ENABLED | false |
+| - | - | restSSLKeyPath | File path
of the HTTP/REST SSL private key (PKCS#8 PEM or PKCS#1 DER). |
SW_ADMIN_SERVER_REST_SSL_KEY_PATH | - |
+| - | - | restSSLCertChainPath | File path
of the HTTP/REST SSL X.509 certificate chain. |
SW_ADMIN_SERVER_REST_SSL_CERT_CHAIN_PATH | - |
| - | - | httpMaxRequestHeaderSize
| Maximum length of all
HTTP/1 request headers accepted by the admin host (bytes).
[...]
| - | - | gRPCHost
| Binding IP of the
admin-internal gRPC bus. Carries peer-to-peer cluster RPCs for runtime-rule
(Suspend/Resume/Forward) and dsl-debugging (install/collect/stop). MUST be a
private peer-to-peer interface — NEVER expose to operators or to the agent
network. Separate from the publ [...]
| - | - | gRPCPort
| Binding port of the
admin-internal gRPC bus. Every OAP node in the cluster MUST use the same value
— peers are dialed at the LOCAL config's port, uniform across the cluster by
convention. | SW_ADMIN_SERVER_GRPC_PORT | 17129
[...]
diff --git a/docs/en/setup/backend/grpc-security.md
b/docs/en/setup/backend/grpc-security.md
index e0f7f52550..62a1b4ca1c 100644
--- a/docs/en/setup/backend/grpc-security.md
+++ b/docs/en/setup/backend/grpc-security.md
@@ -89,3 +89,38 @@ receiver-sharing-server:
You can still use this [script](../../../../tools/TLS/tls_key_generate.sh) to
generate CA certificate and the key files of server-side(for OAP Server) and
client-side(for Agent/Satellite).
You have to notice the keys, including server and client-side, are from the
same CA certificate.
+
+## TLS on OAP HTTP/REST servers
+
+Besides gRPC, the OAP server exposes several HTTP/REST servers. Each one is
configured
+independently and shares the same `restSSL*` configuration structure, with
**dedicated
+environment variables** per server:
+
+| HTTP server | `application.yml` section | Environment variables |
+|-------------|---------------------------|-----------------------|
+| Core REST (GraphQL query API) | `core/default` | `SW_CORE_REST_SSL_ENABLED`
/ `SW_CORE_REST_SSL_KEY_PATH` / `SW_CORE_REST_SSL_CERT_CHAIN_PATH` |
+| Sharing REST receiver | `receiver-sharing-server/default` |
`SW_RECEIVER_SHARING_REST_SSL_ENABLED` /
`SW_RECEIVER_SHARING_REST_SSL_KEY_PATH` /
`SW_RECEIVER_SHARING_REST_SSL_CERT_CHAIN_PATH` |
+| Admin server | `admin-server/default` | `SW_ADMIN_SERVER_REST_SSL_ENABLED` /
`SW_ADMIN_SERVER_REST_SSL_KEY_PATH` /
`SW_ADMIN_SERVER_REST_SSL_CERT_CHAIN_PATH` |
+| PromQL | `promql/default` | `SW_PROMQL_REST_SSL_ENABLED` /
`SW_PROMQL_REST_SSL_KEY_PATH` / `SW_PROMQL_REST_SSL_CERT_CHAIN_PATH` |
+| LogQL | `logql/default` | `SW_LOGQL_REST_SSL_ENABLED` /
`SW_LOGQL_REST_SSL_KEY_PATH` / `SW_LOGQL_REST_SSL_CERT_CHAIN_PATH` |
+| TraceQL | `traceQL/default` | `SW_TRACEQL_REST_SSL_ENABLED` /
`SW_TRACEQL_REST_SSL_KEY_PATH` / `SW_TRACEQL_REST_SSL_CERT_CHAIN_PATH` |
+| Zipkin query | `query-zipkin/default` | `SW_QUERY_ZIPKIN_REST_SSL_ENABLED` /
`SW_QUERY_ZIPKIN_REST_SSL_KEY_PATH` /
`SW_QUERY_ZIPKIN_REST_SSL_CERT_CHAIN_PATH` |
+| Zipkin receiver | `receiver-zipkin/default` |
`SW_RECEIVER_ZIPKIN_REST_SSL_ENABLED` / `SW_RECEIVER_ZIPKIN_REST_SSL_KEY_PATH`
/ `SW_RECEIVER_ZIPKIN_REST_SSL_CERT_CHAIN_PATH` |
+
+For example, to enable TLS on the core REST server under
`application.yml/core/default`:
+
+```yaml
+restSSLEnabled: ${SW_CORE_REST_SSL_ENABLED:true}
+restSSLKeyPath: ${SW_CORE_REST_SSL_KEY_PATH:/path/to/server.pem}
+restSSLCertChainPath: ${SW_CORE_REST_SSL_CERT_CHAIN_PATH:/path/to/server.crt}
+```
+
+* `restSSLKeyPath` is the private key, either PKCS#8(PEM) or PKCS#1(DER).
+* `restSSLCertChainPath` is the X.509 certificate chain.
+
+Each server can point at its own certificate, or you can point several of them
at the same
+mounted certificate (for example a single Kubernetes secret). The HTTP servers
present a
+server certificate only (no client certificate verification / mTLS).
+
+**When the certificate files are rotated in place (for example a refreshed
Kubernetes
+secret), they are reloaded automatically and you do not have to restart an OAP
instance.**
diff --git
a/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleConfig.java
b/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleConfig.java
index 3ebed11ffc..4db757b664 100644
---
a/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleConfig.java
+++
b/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleConfig.java
@@ -40,6 +40,15 @@ public class AdminServerModuleConfig extends ModuleConfig {
private int acceptQueueSize = 0;
private int httpMaxRequestHeaderSize = 8192;
+ /**
+ * TLS settings for the admin HTTP server (env vars {@code
SW_ADMIN_SERVER_REST_SSL_*}).
+ * The certificate and key are read from disk and reloaded on rotation
without a
+ * restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath = "";
+ private String restSSLCertChainPath = "";
+
/**
* Bind address for the admin-internal gRPC host that carries peer-to-peer
* cluster RPCs for admin features (dsl-debugging install/collect/stop,
diff --git
a/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleProvider.java
b/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleProvider.java
index 4afed7db2a..8c1b378c8c 100644
---
a/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleProvider.java
+++
b/oap-server/server-admin/admin-server/src/main/java/org/apache/skywalking/oap/server/admin/server/module/AdminServerModuleProvider.java
@@ -109,6 +109,9 @@ public class AdminServerModuleProvider extends
ModuleProvider {
.acceptQueueSize(moduleConfig.getAcceptQueueSize())
.idleTimeOut(moduleConfig.getIdleTimeOut())
.maxRequestHeaderSize(moduleConfig.getHttpMaxRequestHeaderSize())
+ .enableTLS(moduleConfig.isRestSSLEnabled())
+ .tlsKeyPath(moduleConfig.getRestSSLKeyPath())
+
.tlsCertChainPath(moduleConfig.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
httpServer.setBlockingTaskName("admin-http");
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleConfig.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleConfig.java
index 136a544d37..02e21f10d4 100644
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleConfig.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleConfig.java
@@ -36,6 +36,15 @@ public class CoreModuleConfig extends ModuleConfig {
private int restMaxThreads = 200;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for the core REST server (GraphQL query API). Every OAP
HTTP server
+ * exposes the same {@code restSSL*} structure under its own module with
dedicated
+ * environment variables. The certificate and private key are read from
disk and
+ * reloaded on rotation without a restart.
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
private String gRPCHost;
private int gRPCPort;
diff --git
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
index f617462130..bd6115c041 100755
---
a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
+++
b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
@@ -272,6 +272,9 @@ public class CoreModuleProvider extends ModuleProvider {
moduleConfig.getRestAcceptQueueSize())
.maxRequestHeaderSize(
moduleConfig.getHttpMaxRequestHeaderSize())
+
.enableTLS(moduleConfig.isRestSSLEnabled())
+
.tlsKeyPath(moduleConfig.getRestSSLKeyPath())
+
.tlsCertChainPath(moduleConfig.getRestSSLCertChainPath())
.build();
setBootingParameter("oap.external.http.host",
moduleConfig.getRestHost());
setBootingParameter("oap.external.http.port",
moduleConfig.getRestPort());
diff --git
a/oap-server/server-library/library-server/src/main/java/org/apache/skywalking/oap/server/library/server/http/HTTPServer.java
b/oap-server/server-library/library-server/src/main/java/org/apache/skywalking/oap/server/library/server/http/HTTPServer.java
index 440bd9e2dd..e1e7b94a42 100644
---
a/oap-server/server-library/library-server/src/main/java/org/apache/skywalking/oap/server/library/server/http/HTTPServer.java
+++
b/oap-server/server-library/library-server/src/main/java/org/apache/skywalking/oap/server/library/server/http/HTTPServer.java
@@ -22,6 +22,8 @@ import com.google.common.collect.Sets;
import com.linecorp.armeria.common.HttpMethod;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
+import com.linecorp.armeria.common.TlsKeyPair;
+import com.linecorp.armeria.common.TlsProvider;
import com.linecorp.armeria.common.util.EventLoopGroups;
import com.linecorp.armeria.server.Route;
import com.linecorp.armeria.server.ServerBuilder;
@@ -114,6 +116,13 @@ public class HTTPServer implements Server {
*/
private static final EventLoopGroup SHARED_WORKER_GROUP;
+ /**
+ * How often the TLS key pair is re-read from disk. Certificates mounted
from a
+ * Kubernetes secret are rotated in place, so the server reloads them
periodically
+ * without a restart. Mirrors the gRPC server's file-change monitor
cadence.
+ */
+ private static final Duration TLS_RELOAD_INTERVAL = Duration.ofSeconds(10);
+
static {
final int cores = Runtime.getRuntime().availableProcessors();
SHARED_WORKER_GROUP = EventLoopGroups.newEventLoopGroup(Math.min(5,
cores));
@@ -164,12 +173,11 @@ public class HTTPServer implements Server {
sb.https(new InetSocketAddress(
config.getHost(),
config.getPort()));
- try (InputStream cert = new
FileInputStream(config.getTlsCertChainPath());
- InputStream key =
PrivateKeyUtil.loadDecryptionKey(config.getTlsKeyPath())) {
- sb.tls(cert, key);
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
+ // Reload the key pair from disk on a schedule so rotated
certificates
+ // (e.g. a refreshed Kubernetes secret) are picked up without a
restart.
+ sb.tlsProvider(TlsProvider.ofScheduled(
+ () -> loadTlsKeyPair(config.getTlsKeyPath(),
config.getTlsCertChainPath()),
+ TLS_RELOAD_INTERVAL));
} else {
sb.http(new InetSocketAddress(
config.getHost(),
@@ -237,6 +245,24 @@ public class HTTPServer implements Server {
sb.build().start().join();
}
+ /**
+ * Read the private key and certificate chain from disk into a {@link
TlsKeyPair}.
+ * Invoked once at startup and then periodically by the TLS provider, so
rotated
+ * files on disk are reflected on the next read.
+ *
+ * @param tlsKeyPath file path of the private key (PKCS#8 PEM or
PKCS#1 DER).
+ * @param tlsCertChainPath file path of the X.509 certificate chain.
+ * @return the key pair loaded from the current contents of the files.
+ */
+ static TlsKeyPair loadTlsKeyPair(final String tlsKeyPath, final String
tlsCertChainPath) {
+ try (InputStream key = PrivateKeyUtil.loadDecryptionKey(tlsKeyPath);
+ InputStream cert = new FileInputStream(tlsCertChainPath)) {
+ return TlsKeyPair.of(key, cert);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
private String transformAbsoluteURI(final String uri) {
if (uri.startsWith("https://")) {
return uri.substring(uri.indexOf("/", 8));
diff --git
a/oap-server/server-library/library-server/src/test/java/org/apache/skywalking/oap/server/library/server/http/HTTPServerTLSTest.java
b/oap-server/server-library/library-server/src/test/java/org/apache/skywalking/oap/server/library/server/http/HTTPServerTLSTest.java
new file mode 100644
index 0000000000..0c0783c6bc
--- /dev/null
+++
b/oap-server/server-library/library-server/src/test/java/org/apache/skywalking/oap/server/library/server/http/HTTPServerTLSTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.library.server.http;
+
+import com.linecorp.armeria.common.TlsKeyPair;
+import io.netty.handler.ssl.util.SelfSignedCertificate;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+class HTTPServerTLSTest {
+
+ @Test
+ void shouldLoadKeyPairFromDisk(@TempDir Path dir) throws Exception {
+ final SelfSignedCertificate cert = new
SelfSignedCertificate("localhost");
+ final Path keyPath = dir.resolve("server.key");
+ final Path certPath = dir.resolve("server.crt");
+ Files.copy(cert.privateKey().toPath(), keyPath);
+ Files.copy(cert.certificate().toPath(), certPath);
+
+ final TlsKeyPair keyPair =
+ HTTPServer.loadTlsKeyPair(keyPath.toString(), certPath.toString());
+
+ assertThat(keyPair.privateKey()).isNotNull();
+ assertThat(keyPair.certificateChain()).isNotEmpty();
+ }
+
+ /**
+ * The TLS provider re-invokes {@link HTTPServer#loadTlsKeyPair} on a
schedule, so
+ * overwriting the files in place (as happens when a Kubernetes secret is
rotated)
+ * must yield the new certificate on the next read.
+ */
+ @Test
+ void shouldPickUpRotatedCertificate(@TempDir Path dir) throws Exception {
+ final Path keyPath = dir.resolve("server.key");
+ final Path certPath = dir.resolve("server.crt");
+
+ final SelfSignedCertificate first = new
SelfSignedCertificate("localhost");
+ Files.copy(first.privateKey().toPath(), keyPath);
+ Files.copy(first.certificate().toPath(), certPath);
+ final TlsKeyPair before =
+ HTTPServer.loadTlsKeyPair(keyPath.toString(), certPath.toString());
+
+ // Rotate: overwrite the same paths with a freshly generated
certificate.
+ final SelfSignedCertificate second = new
SelfSignedCertificate("localhost");
+ Files.copy(second.privateKey().toPath(), keyPath,
StandardCopyOption.REPLACE_EXISTING);
+ Files.copy(second.certificate().toPath(), certPath,
StandardCopyOption.REPLACE_EXISTING);
+ final TlsKeyPair after =
+ HTTPServer.loadTlsKeyPair(keyPath.toString(), certPath.toString());
+
+ assertThat(after.certificateChain())
+ .as("rotated certificate should be read back from disk")
+ .isNotEqualTo(before.certificateChain());
+ }
+
+ @Test
+ void shouldFailWhenFilesMissing() {
+ assertThatThrownBy(() -> HTTPServer.loadTlsKeyPair("/no/such.key",
"/no/such.crt"))
+ .isInstanceOf(IllegalArgumentException.class);
+ }
+}
diff --git
a/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLConfig.java
b/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLConfig.java
index 902c9367d7..59f81171af 100644
---
a/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLConfig.java
+++
b/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLConfig.java
@@ -30,4 +30,11 @@ public class LogQLConfig extends ModuleConfig {
private String restContextPath;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for this HTTP server. The certificate and key are read
from disk and
+ * reloaded on rotation without a restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
}
diff --git
a/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLProvider.java
b/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLProvider.java
index 7299b35149..207fa065cc 100644
---
a/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLProvider.java
+++
b/oap-server/server-query-plugin/logql-plugin/src/main/java/org/apache/skywalking/oap/query/logql/LogQLProvider.java
@@ -73,6 +73,9 @@ public class LogQLProvider extends ModuleProvider {
.contextPath(config.getRestContextPath())
.idleTimeOut(config.getRestIdleTimeOut())
.acceptQueueSize(config.getRestAcceptQueueSize())
+
.enableTLS(config.isRestSSLEnabled())
+
.tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
diff --git
a/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLConfig.java
b/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLConfig.java
index c06ebec030..d57a273be5 100644
---
a/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLConfig.java
+++
b/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLConfig.java
@@ -30,6 +30,13 @@ public class PromQLConfig extends ModuleConfig {
private String restContextPath;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for this HTTP server. The certificate and key are read
from disk and
+ * reloaded on rotation without a restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
// The following configs are used to build `/api/v1/status/buildinfo` API
response.
private String buildInfoVersion = "2.45.0"; // Declare compatibility with
2.45 LTS version APIs.
diff --git
a/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLProvider.java
b/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLProvider.java
index 62c9fc0cb6..921a9c6bc1 100644
---
a/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLProvider.java
+++
b/oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/PromQLProvider.java
@@ -74,6 +74,9 @@ public class PromQLProvider extends ModuleProvider {
.contextPath(config.getRestContextPath())
.idleTimeOut(config.getRestIdleTimeOut())
.acceptQueueSize(config.getRestAcceptQueueSize())
+
.enableTLS(config.isRestSSLEnabled())
+
.tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
diff --git
a/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLConfig.java
b/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLConfig.java
index 8eab6061cd..295cbe9125 100644
---
a/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLConfig.java
+++
b/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLConfig.java
@@ -34,6 +34,13 @@ public class TraceQLConfig extends ModuleConfig {
private String restContextPathSkywalking;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for this HTTP server. The certificate and key are read
from disk and
+ * reloaded on rotation without a restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
private long lookback = 86400000L;
private String zipkinTracesListResultTags = ZIPKIN_TRACES_LIST_RESULT_TAGS;
private String skywalkingTracesListResultTags =
SKYWALKING_TRACES_LIST_RESULT_TAGS;
diff --git
a/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLProvider.java
b/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLProvider.java
index 0d59f61d48..5c054b91b0 100644
---
a/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLProvider.java
+++
b/oap-server/server-query-plugin/traceql-plugin/src/main/java/org/apache/skywalking/oap/query/traceql/TraceQLProvider.java
@@ -75,6 +75,9 @@ public class TraceQLProvider extends ModuleProvider {
"/") // Base
context path for the server, individual handlers will have their own context
paths
.idleTimeOut(config.getRestIdleTimeOut())
.acceptQueueSize(config.getRestAcceptQueueSize())
+
.enableTLS(config.isRestSSLEnabled())
+
.tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
diff --git
a/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryConfig.java
b/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryConfig.java
index 987a4daf66..d5440a6c67 100644
---
a/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryConfig.java
+++
b/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryConfig.java
@@ -30,6 +30,13 @@ public class ZipkinQueryConfig extends ModuleConfig {
private String restContextPath;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for this HTTP server. The certificate and key are read
from disk and
+ * reloaded on rotation without a restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
private long lookback = 86400000L;
private int namesMaxAge = 300;
private int uiQueryLimit = 10;
diff --git
a/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryProvider.java
b/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryProvider.java
index aa5ff0141e..a948a2405d 100644
---
a/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryProvider.java
+++
b/oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/ZipkinQueryProvider.java
@@ -74,6 +74,9 @@ public class ZipkinQueryProvider extends ModuleProvider {
.contextPath(config.getRestContextPath())
.idleTimeOut(config.getRestIdleTimeOut())
.acceptQueueSize(config.getRestAcceptQueueSize())
+
.enableTLS(config.isRestSSLEnabled())
+
.tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
diff --git
a/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerConfig.java
b/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerConfig.java
index b349856348..bbf350e9ec 100644
---
a/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerConfig.java
+++
b/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerConfig.java
@@ -33,6 +33,14 @@ public class SharingServerConfig extends ModuleConfig {
private String restContextPath;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for the sharing REST server (env vars {@code
SW_RECEIVER_SHARING_REST_SSL_*}).
+ * The certificate and key are read from disk and reloaded on rotation
without a
+ * restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
private String gRPCHost;
/**
diff --git
a/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerModuleProvider.java
b/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerModuleProvider.java
index 7a67823372..638f18db4f 100644
---
a/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerModuleProvider.java
+++
b/oap-server/server-receiver-plugin/skywalking-sharing-server-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/sharing/server/SharingServerModuleProvider.java
@@ -81,7 +81,11 @@ public class SharingServerModuleProvider extends
ModuleProvider {
.contextPath(config.getRestContextPath())
.acceptQueueSize(config.getRestAcceptQueueSize())
.idleTimeOut(config.getRestIdleTimeOut())
-
.maxRequestHeaderSize(config.getHttpMaxRequestHeaderSize()).build();
+
.maxRequestHeaderSize(config.getHttpMaxRequestHeaderSize())
+ .enableTLS(config.isRestSSLEnabled())
+ .tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
+ .build();
httpServerConfig.setHost(Strings.isBlank(config.getRestHost()) ?
"0.0.0.0" : config.getRestHost());
httpServerConfig.setPort(config.getRestPort());
httpServerConfig.setContextPath(config.getRestContextPath());
diff --git
a/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverConfig.java
b/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverConfig.java
index 10b48d3592..3c2ab0af3d 100644
---
a/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverConfig.java
+++
b/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverConfig.java
@@ -33,6 +33,13 @@ public class ZipkinReceiverConfig extends ModuleConfig {
private String restContextPath;
private long restIdleTimeOut = 30000;
private int restAcceptQueueSize = 0;
+ /**
+ * TLS settings for this HTTP server. The certificate and key are read
from disk and
+ * reloaded on rotation without a restart. Server-side TLS only (no mTLS).
+ */
+ private boolean restSSLEnabled = false;
+ private String restSSLKeyPath;
+ private String restSSLCertChainPath;
private String searchableTracesTags = DEFAULT_SEARCHABLE_TAG_KEYS;
private int sampleRate = 10000;
private int maxSpansPerSecond = 0;
diff --git
a/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverProvider.java
b/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverProvider.java
index e94d46fac5..2a26bb3181 100644
---
a/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverProvider.java
+++
b/oap-server/server-receiver-plugin/zipkin-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/zipkin/ZipkinReceiverProvider.java
@@ -86,6 +86,9 @@ public class ZipkinReceiverProvider extends ModuleProvider {
.contextPath(config.getRestContextPath())
.idleTimeOut(config.getRestIdleTimeOut())
.acceptQueueSize(config.getRestAcceptQueueSize())
+
.enableTLS(config.isRestSSLEnabled())
+
.tlsKeyPath(config.getRestSSLKeyPath())
+
.tlsCertChainPath(config.getRestSSLCertChainPath())
.build();
httpServer = new HTTPServer(httpServerConfig);
diff --git a/oap-server/server-starter/src/main/resources/application.yml
b/oap-server/server-starter/src/main/resources/application.yml
index eccd933d0c..9fa3eeb315 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -77,6 +77,12 @@ core:
restIdleTimeOut: ${SW_CORE_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_CORE_REST_QUEUE_SIZE:0}
httpMaxRequestHeaderSize: ${SW_CORE_HTTP_MAX_REQUEST_HEADER_SIZE:8192}
+ # TLS for the core REST server (GraphQL query API). Every OAP HTTP server
exposes the
+ # same restSSL* structure with its own env vars; the cert and key are
reloaded on
+ # rotation without a restart. Server-side TLS only (no mTLS).
+ restSSLEnabled: ${SW_CORE_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_CORE_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_CORE_REST_SSL_CERT_CHAIN_PATH:""}
gRPCHost: ${SW_CORE_GRPC_HOST:0.0.0.0}
gRPCPort: ${SW_CORE_GRPC_PORT:11800}
maxConcurrentCallsPerConnection: ${SW_CORE_GRPC_MAX_CONCURRENT_CALL:0}
@@ -257,6 +263,10 @@ receiver-sharing-server:
restIdleTimeOut: ${SW_RECEIVER_SHARING_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_RECEIVER_SHARING_REST_QUEUE_SIZE:0}
httpMaxRequestHeaderSize:
${SW_RECEIVER_SHARING_HTTP_MAX_REQUEST_HEADER_SIZE:8192}
+ # TLS for the sharing REST server; reloaded on rotation without a restart.
+ restSSLEnabled: ${SW_RECEIVER_SHARING_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_RECEIVER_SHARING_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_RECEIVER_SHARING_REST_SSL_CERT_CHAIN_PATH:""}
# For gRPC server
gRPCHost: ${SW_RECEIVER_GRPC_HOST:0.0.0.0}
gRPCPort: ${SW_RECEIVER_GRPC_PORT:0}
@@ -408,6 +418,9 @@ receiver-zipkin:
restContextPath: ${SW_RECEIVER_ZIPKIN_REST_CONTEXT_PATH:/}
restIdleTimeOut: ${SW_RECEIVER_ZIPKIN_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_RECEIVER_ZIPKIN_REST_QUEUE_SIZE:0}
+ restSSLEnabled: ${SW_RECEIVER_ZIPKIN_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_RECEIVER_ZIPKIN_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_RECEIVER_ZIPKIN_REST_SSL_CERT_CHAIN_PATH:""}
## The below configs are for OAP collect zipkin trace from kafka
enableKafkaCollector: ${SW_ZIPKIN_KAFKA_COLLECTOR_ENABLED:false}
kafkaBootstrapServers: ${SW_ZIPKIN_KAFKA_SERVERS:localhost:9092}
@@ -456,6 +469,9 @@ query-zipkin:
restContextPath: ${SW_QUERY_ZIPKIN_REST_CONTEXT_PATH:/zipkin}
restIdleTimeOut: ${SW_QUERY_ZIPKIN_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_QUERY_ZIPKIN_REST_QUEUE_SIZE:0}
+ restSSLEnabled: ${SW_QUERY_ZIPKIN_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_QUERY_ZIPKIN_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_QUERY_ZIPKIN_REST_SSL_CERT_CHAIN_PATH:""}
# Default look back for traces and autocompleteTags, 1 day in millis
lookback: ${SW_QUERY_ZIPKIN_LOOKBACK:86400000}
# The Cache-Control max-age (seconds) for serviceNames, remoteServiceNames
and spanNames
@@ -476,6 +492,9 @@ promql:
restContextPath: ${SW_PROMQL_REST_CONTEXT_PATH:/}
restIdleTimeOut: ${SW_PROMQL_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_PROMQL_REST_QUEUE_SIZE:0}
+ restSSLEnabled: ${SW_PROMQL_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_PROMQL_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_PROMQL_REST_SSL_CERT_CHAIN_PATH:""}
# The below config is for the API buildInfo, set the value to mock the
build info.
buildInfoVersion: ${SW_PROMQL_BUILD_INFO_VERSION:"2.45.0"}
buildInfoRevision: ${SW_PROMQL_BUILD_INFO_REVISION:""}
@@ -494,6 +513,9 @@ logql:
restContextPath: ${SW_LOGQL_REST_CONTEXT_PATH:/}
restIdleTimeOut: ${SW_LOGQL_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_LOGQL_REST_QUEUE_SIZE:0}
+ restSSLEnabled: ${SW_LOGQL_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_LOGQL_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_LOGQL_REST_SSL_CERT_CHAIN_PATH:""}
traceQL:
selector: ${SW_TRACEQL:-}
@@ -506,6 +528,9 @@ traceQL:
restContextPathSkywalking:
${SW_TRACEQL_REST_CONTEXT_PATH_SKYWALKING:/skywalking}
restIdleTimeOut: ${SW_TRACEQL_REST_IDLE_TIMEOUT:30000}
restAcceptQueueSize: ${SW_TRACEQL_REST_QUEUE_SIZE:0}
+ restSSLEnabled: ${SW_TRACEQL_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_TRACEQL_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_TRACEQL_REST_SSL_CERT_CHAIN_PATH:""}
# If the query does not provide the start time (the default end time is
current), the default lookback for traces and autocompleteTags is 1 day in
milliseconds.
lookback: ${SW_TRACEQL_LOOKBACK:86400000}
# The tags in the list result of traces query, which would be used for
trace grouping and shown in the trace list page.
@@ -688,6 +713,10 @@ admin-server:
idleTimeOut: ${SW_ADMIN_SERVER_IDLE_TIMEOUT:30000}
acceptQueueSize: ${SW_ADMIN_SERVER_QUEUE_SIZE:0}
httpMaxRequestHeaderSize:
${SW_ADMIN_SERVER_HTTP_MAX_REQUEST_HEADER_SIZE:8192}
+ # TLS for the admin HTTP server; reloaded on rotation without a restart.
+ restSSLEnabled: ${SW_ADMIN_SERVER_REST_SSL_ENABLED:false}
+ restSSLKeyPath: ${SW_ADMIN_SERVER_REST_SSL_KEY_PATH:""}
+ restSSLCertChainPath: ${SW_ADMIN_SERVER_REST_SSL_CERT_CHAIN_PATH:""}
# Admin-internal gRPC bus — peer-to-peer RPCs for runtime-rule
# (Suspend/Resume/Forward) and dsl-debugging (install/collect/stop).
# MUST be a private interface reachable between OAP nodes ONLY.
diff --git a/test/e2e-v2/cases/storage/expected/config-dump.yml
b/test/e2e-v2/cases/storage/expected/config-dump.yml
index 6f07b0f406..6f73abc5a2 100644
--- a/test/e2e-v2/cases/storage/expected/config-dump.yml
+++ b/test/e2e-v2/cases/storage/expected/config-dump.yml
@@ -30,6 +30,9 @@
"admin-server.default.idleTimeOut": "30000",
"admin-server.default.internalCommunicationTimeout": "5000",
"admin-server.default.port": "17128",
+ "admin-server.default.restSSLCertChainPath": "",
+ "admin-server.default.restSSLEnabled": "false",
+ "admin-server.default.restSSLKeyPath": "",
"admin-server.provider": "default",
"agent-analyzer.default.forceSampleErrorSegment": "true",
"agent-analyzer.default.meterAnalyzerActiveFiles":
"datasource,threadpool,satellite,go-runtime,python-runtime,continuous-profiling,java-agent,go-agent,ruby-runtime,php-runtime,nodejs-runtime",
@@ -94,6 +97,9 @@
"core.default.restHost": "0.0.0.0",
"core.default.restIdleTimeOut": "30000",
"core.default.restPort": "12800",
+ "core.default.restSSLCertChainPath": "",
+ "core.default.restSSLEnabled": "false",
+ "core.default.restSSLKeyPath": "",
"core.default.role": "Mixed",
"core.default.searchableAlarmTags": "level",
"core.default.searchableLogsTags": "level,http.status_code,ai_route_type",
@@ -137,6 +143,9 @@
"logql.default.restHost": "0.0.0.0",
"logql.default.restIdleTimeOut": "30000",
"logql.default.restPort": "3100",
+ "logql.default.restSSLCertChainPath": "",
+ "logql.default.restSSLEnabled": "false",
+ "logql.default.restSSLKeyPath": "",
"logql.provider": "default",
"promql.default.buildInfoBranch": "",
"promql.default.buildInfoBuildDate": "",
@@ -149,6 +158,9 @@
"promql.default.restHost": "0.0.0.0",
"promql.default.restIdleTimeOut": "30000",
"promql.default.restPort": "9090",
+ "promql.default.restSSLCertChainPath": "",
+ "promql.default.restSSLEnabled": "false",
+ "promql.default.restSSLKeyPath": "",
"promql.provider": "default",
"query.graphql.enableLogTestTool": "false",
"query.graphql.enableOnDemandPodLog": "false",
@@ -203,6 +215,9 @@
"receiver-sharing-server.default.restHost": "0.0.0.0",
"receiver-sharing-server.default.restIdleTimeOut": "30000",
"receiver-sharing-server.default.restPort": "0",
+ "receiver-sharing-server.default.restSSLCertChainPath": "",
+ "receiver-sharing-server.default.restSSLEnabled": "false",
+ "receiver-sharing-server.default.restSSLKeyPath": "",
"receiver-sharing-server.provider": "default",
"receiver-telegraf.default.activeFiles": "vm",
"receiver-telegraf.provider": "default",