Skip to main content
版本:v2.0.0

Security

Audience: operators and embedders securing an EventMesh deployment — auth/ACL/quota/audit at the traffic plane, TLS on the wire, and the admin plane's token guard.


The unified SecurityGate

SecurityGate (issue #5304) is an opt-in per-request gate installed at every ingress point. When installed, each request flows through one immutable RequestContext and is checked in order:

   ingress request


SecurityGate.check(RequestContext, EventMeshFrame)

├─ 1. FilterChain.invoke(frame) TokenAuthFilter → SignatureVerifierFilter → AclFilter
│ verdict: ALLOW / DENY
├─ 2. if ALLOW → QuotaManager.acquire(ctx, Resource)
│ Resources: CONNECTIONS | SUBSCRIPTIONS | THROUGHPUT | BACKLOG
└─ 3. AuditSink.emit(decision, ctx, frame) LoggingAuditSink (default) or custom

Any rejection short-circuits downstream — the request never touches the storage SPI. Rejections map to HTTP 401 (unauthenticated), 403 (forbidden), 429 (quota exceeded).

Design points

  • One context per request. RequestContext (builder-built, immutable) carries tenantId, principal, roles, scopes, credential, remoteAddress, source, traceContext, quotaKey, and an Operation enum (PUBLISH / SUBSCRIBE / ACK / CONNECTOR / A2A / ADMIN).
  • The gate composes policy, it does not duplicate it. The existing FilterChain (TokenAuthFilter, SignatureVerifierFilter, AclFilter) still produces the auth/ACL verdict; new filters drop in without touching the gate.
  • Quota is keyed by RequestContext.quotaKey() (defaults to tenantId) against a Resource enum — TenantQuotaManager is the in-memory implementation, QuotaManager.unlimited() disables enforcement.
  • Audit is best-effort by design: an AuditSink failure is logged and must not take down the data path.
  • Fail-safe on malformed ACL entries: logged at WARN, request denied, deny counted in gate metrics.

Wiring points

IngressBuilder
Traffic HTTP (/events/*, SSE, WS upgrade)UniHttpServer#withSecurityGate(gate)
A2A gatewayA2AGatewayHttpHandler#withSecurityGate(gate)
Connector schedulingConnectorScheduler#withSecurityGate(gate) (rejects with ConnectorAccessDeniedException → HTTP 403)
Embedder bootstrapEventMeshApplication#withSecurityGate(gate) — installed into the traffic server at start()

When no gate is installed the runtime behaves as before (open) — but new endpoints are expected to install one, and embedders can fail closed at boot before serving traffic.

Rate limiting (per-topic)

UniIngressService enforces an optional per-topic token bucket (configureTopicRateLimit(topic, capacity, permitsPerSecond)). Exhausted buckets fail publish with RateLimitedException → HTTP 429. Cluster-wide limits are inspectable/adjustable at /admin/ratelimit — see Admin API.

TLS / mTLS on the traffic port

TLS terminates at the traffic HTTP server. Keys (read at boot by EventMeshApplication):

KeyDefaultPurpose
eventmesh.tls.keystoreKeystore path; empty = plain HTTP
eventmesh.tls.keystore.passwordKeystore password
eventmesh.tls.truststoreTruststore for client certs (mTLS)
eventmesh.tls.truststore.passwordTruststore password
eventmesh.tls.protocolTLSv1.3TLS protocol
eventmesh.tls.needClientAuthfalsetrue + truststore → require client certificates

Embedders can instead call withTls(SSLContext) / withClientAuth(boolean) before start().

Admin plane: fail-closed token guard (issue #5364)

Every admin endpoint except /admin/health is wrapped by a bearer-token guard (-Deventmesh.admin.token=<secret>):

  • Missing/wrong Authorization: Bearer <token>401.
  • No token configured at all → 503 admin_locked — the admin API is fail-closed by default; an operator who never set a token cannot use it accidentally. Only /admin/health (liveness probe) is exempt.
  • The comparison is constant-time (MessageDigest.isEqual).

Where the code lives

PieceLocation
Gate coreeventmesh-runtime/.../security/gate/SecurityGate.java, RequestContext.java, GateDecision.java
Quotasecurity/gate/QuotaManager.java, TenantQuotaManager.java, UnlimitedQuotaManager.java
Auditsecurity/gate/AuditSink.java, LoggingAuditSink.java, DisabledAuditSink.java
Auth/ACL filterseventmesh-runtime/.../security/TokenAuthFilter.java, SignatureVerifierFilter.java, AclFilter.java
TLS factoryeventmesh-runtime/.../http/TlsContextFactory.java
Admin guardeventmesh-runtime/.../admin/UniAdminServer.java (guarded() / authorized())
TestsSecurityGateTest (per-Resource allow/deny, every Operation, short-circuit), TlsIntegrationTest, RateLimitIntegrationTest