An Apache Flink cluster runs long lived jobs that hold credentials for Kafka, HDFS and other sources, and its REST endpoint and web dashboard can start, cancel and inspect those jobs, so who can reach that endpoint decides who controls the streaming estate. Flink's design puts these decisions with the operator: TLS is configured separately for internal and external traffic, client authentication for the REST endpoint is provided by mutual TLS or, as the project recommends, an authenticating proxy, and isolation comes from the deployment mode. This guide covers those customer side controls: SSL and mutual TLS, Kerberos and delegation tokens, protecting the dashboard and job submission, separating jobs and credentials, and the logging that shows misuse. It is written for streaming platform engineers, Kubernetes and YARN operators and security architects. For the messaging side of most Flink pipelines, see the Kafka Security Guide.
This is an independent guide from NHI Mgmt Group, based on the Apache Flink project's public documentation as of November 2026. It is not sponsored or reviewed by the Apache Software Foundation. Product features change, so confirm settings against the current Flink documentation for your release.
Key takeaways
- Put authentication in front of REST. The REST endpoint accepts connections from any client unless mutual TLS is turned on, so bind it to loopback or the pod interface and front it with an authenticating sidecar proxy, as the Flink documentation recommends.
- Turn on both TLS layers.
security.ssl.internal.enabledgives mutual TLS between JobManager, TaskManagers and the blob service;security.ssl.rest.enabledencrypts the dashboard, CLI and REST API. Both are off until you enable them. - Control job submission at the API, not just the UI.
web.submit.enable: falsecontrols upload from the web frontend; access to the REST API is the real control. - Isolate by cluster. All jobs in a cluster share its Kerberos credential and TaskManagers, so use Application Mode or separate session clusters per team or trust level.
- Prefer keytabs and delegation tokens to shared caches. Keytab login is the documented preferred method for long running jobs, and delegation tokens keep long lived credentials on the JobManager only.
How identity and access work in Apache Flink
Flink separates internal connectivity, which only Flink processes use, from external connectivity, which people and tools use. Each has its own TLS settings, and the trust model differs.
| Connectivity | What it carries | How it is secured |
|---|---|---|
| Internal: RPC | Control messages between JobManager, TaskManagers, Dispatcher and ResourceManager | Mutual TLS with a dedicated certificate under security.ssl.internal.* |
| Internal: data plane | Shuffles, broadcasts and redistribution between TaskManagers | Same internal mTLS (taskmanager.data.ssl.enabled) |
| Internal: blob service | Distribution of job libraries and artefacts | Same internal mTLS (blob.service.ssl.enabled) |
| External: REST and web UI | Job submission (session clusters), job inspection, cancellation, CLI traffic | TLS under security.ssl.rest.*; client authentication through security.ssl.rest.authentication-enabled or an authenticating proxy |
| Outbound to data systems | Kafka, HDFS, HBase, ZooKeeper and other connectors | Kerberos (keytab or ticket cache), delegation tokens, or each connector's own TLS and credential options |
Internal mutual TLS
For internal traffic the certificate acts as a shared secret. The documentation's simplest pattern is a dedicated key pair and self signed certificate for the deployment, used as both keystore and truststore and baked into the container image or attached to the YARN deployment. Where policy requires a company internal CA, keep a dedicated certificate for the Flink deployment and set security.ssl.internal.cert.fingerprint to pin it, so the truststore does not accept every certificate that CA has signed. Because peers authenticate with the shared certificate, Flink can skip hostname verification internally, which suits containers.
External TLS and client authentication
With security.ssl.rest.enabled: true, the keystore serves the REST endpoint and the truststore lets clients, including the CLI, accept its certificate. The certificate's common name or subject alternative names should match the node's hostname and IP. Setting security.ssl.rest.authentication-enabled: true requires clients to present certificates (simple mutual authentication). For people and richer policies, the project recommends a sidecar proxy: bind the REST endpoint to the loopback or pod local interface with rest.bind-address and let the proxy authenticate users and forward requests. Proxies such as Envoy or NGINX with an auth request module give single sign-on, group based access and request logs. See the mTLS Guide.
Cipher suites and protocols
Current Flink documentation lists a default security.ssl.protocol of TLSv1.2,TLSv1.3 and a default security.ssl.algorithms made of forward secret ECDHE suites plus the TLS 1.3 suites, aligned with IETF RFC 9325. Defaults have changed across releases, so confirm the current values in the documentation for your version and set both properties explicitly if your policy requires a fixed list.
Admin roles and privileged access
Flink's REST endpoint is built to sit behind the access controls of the surrounding platform, so administrative roles are defined in the proxy, the orchestrator and the host rather than inside Flink. Anyone who can call REST on a session cluster can submit, cancel and inspect jobs, which makes REST access the most privileged permission in the estate.
| Capability | Where it is granted | How to control it |
|---|---|---|
| Submit or run jobs on a session cluster | REST API (/jars upload and run endpoints) and web UI | Proxy policy limited to a deployment group or CI pipeline; web.submit.enable: false for the UI |
| Cancel jobs | REST API and web UI | Proxy policy for operators; web.cancel.enable: false for the UI |
| View job graphs, configuration and exceptions | Web UI and REST | Read only proxy role for developers; treat job configuration as sensitive |
| Deploy and change clusters | Kubernetes RBAC, YARN queues or host access | Namespace scoped permissions for the Flink Kubernetes Operator and its custom resources; named administrators only |
| Read keystores, keytabs and config | Host or pod filesystem, Kubernetes Secrets | Mount as read only secrets, restrict to the Flink service account |
| Read archived jobs | History server (binds to localhost on port 8082 by default) | Keep it on loopback or behind the same authenticating proxy |
The two UI flags are a useful extra layer, not a boundary. Flink's configuration reference (release 2.3) describes web.submit.enable and web.cancel.enable as controlling the web frontend, so treat the REST API as the control point and confirm the behaviour of your version in a test cluster. Write the proxy rules so only the deployment pipeline can reach the upload and run endpoints, and give everyone else read access at most.
Integrations, API tokens and service accounts
Every Flink cluster runs with one set of credentials for external systems, and the documentation is explicit that all jobs share the credential configured for a cluster. To give a job a different keytab, launch a separate cluster with its own configuration. That makes the cluster the unit of identity, and the credential a non-human identity to manage like any other. See the Service Account Security Guide.
Kerberos options
| Option | Settings | When to use |
|---|---|---|
| Keytab (documented as preferred) | security.kerberos.login.keytab, security.kerberos.login.principal | Long running streaming jobs; components renew the TGT automatically |
| Credential cache | security.kerberos.login.use-ticket-cache after kinit | Short or interactive runs; the user keeps the cache current, since it expires |
| Delegation tokens | Obtained by the JobManager for Hadoop file systems (including security.kerberos.access.hadoopFileSystems) and HBase | Keep long lived credentials on the JobManager and give TaskManagers service specific tokens |
Kerberos is supported for Kafka, HDFS, HBase and ZooKeeper, and each can be enabled independently. In native Kubernetes and YARN modes the keytab is copied from the client to the containers, and security.kerberos.krb5-conf.path can ship the Kerberos configuration. Treat the client machine that holds the keytab as privileged. Delegation token support was added in Flink 1.17 as an experimental feature; test renewal before relying on it for production jobs. For keytab lifecycle, see the Linux Service Accounts and Keytab Management Guide.
Connector credentials and secrets
- Keep secrets out of job JARs and SQL: pass connector passwords and keys at deploy time from a secrets store rather than embedding them in code, job parameters or SQL DDL that the dashboard can display.
- Use Kubernetes Secrets or a secrets manager: mount keystores, truststores and keytabs as read only volumes. See the Kubernetes Secrets Security Guide.
- Scope each cluster's identity: grant the Kafka principal or HDFS identity only the topics and paths that cluster's jobs need.
- Pipeline identities: the CI system that submits jobs should use its own credential at the proxy, separate from human operators.
- Managed Flink services: where a cloud provider runs Flink for you, the provider's IAM roles replace keytabs and the REST proxy; apply the same least privilege and separation per application.
Logging and detection
Because the authenticating proxy sees every REST call, its access log is the primary audit trail for who submitted, cancelled or inspected jobs. Combine it with Flink's own JobManager and TaskManager logs and the orchestrator's audit log.
| Signal | Source | What it can indicate |
|---|---|---|
POST to /jars/upload or run endpoints from an unexpected identity | Proxy access log | Job submission outside the deployment pipeline |
| Direct connections to port 8081 that bypass the proxy | Network flow logs, Kubernetes network policy logs | REST endpoint bound to a routable interface |
| New job names or JAR hashes | JobManager log, REST job list | Unapproved code running with the cluster's credentials |
| Job cancellations and savepoint triggers | Proxy access log, JobManager log | Disruption or tampering with state |
| Changes to FlinkDeployment and FlinkSessionJob resources | Kubernetes audit log | Cluster or job changes outside change control |
| Kerberos login and renewal failures | JobManager and TaskManager logs, KDC logs | Expired caches, revoked keytabs or misuse of a principal |
Metrics that show it is working
- Share of Flink clusters whose REST endpoint is reachable only through the authenticating proxy (target 100%).
- Share of clusters with both internal and REST TLS enabled.
- Jobs submitted outside the CI pipeline per month (target zero).
- Number of distinct jobs per credential, aiming for one team or trust level per cluster.
- Days since each keytab and keystore was last rotated.
Hardening baseline
- Inventory clusters: list every session and application cluster, its deployment mode, the credentials it holds and who can reach port 8081.
- Bind REST locally: set
rest.bind-addressto loopback or the pod interface and add an authenticating sidecar proxy. Test the dashboard and CLI through the proxy before closing direct access. - Enable REST TLS: set
security.ssl.rest.enabled: truewith a certificate matching the service hostname, or terminate TLS at the proxy and keep the backend on loopback. - Enable internal mTLS: generate a dedicated deployment certificate, set
security.ssl.internal.enabled: true, pin it withsecurity.ssl.internal.cert.fingerprintif a shared CA signed it, and keep the data, blob and RPC sub-options on. - Restrict submission: set
web.submit.enable: falseandweb.cancel.enable: falseon production session clusters and allow only the pipeline identity to call upload and run endpoints at the proxy. - Choose isolation: move sensitive workloads to Application Mode, which creates a cluster per application, or to dedicated session clusters per team, so one job cannot affect another's TaskManagers or credentials.
- Set up Kerberos with keytabs: use per cluster principals, store keytabs as secrets and plan rotation.
- Protect the history server: keep it on localhost (its default) or behind the proxy, and restrict the archive directory set by
jobmanager.archive.fs.dir. - Network policy: allow internal ports only between Flink pods or hosts and expose nothing but the proxy.
- Patch and roll back safely: apply Flink security releases promptly, taking a savepoint before each upgrade so jobs can be restored on the previous version if needed.
Framework mapping
| Control area | NIST CSF 2.0 | NIST SP 800-53 Rev 5 | ISO/IEC 27001:2022 Annex A |
|---|---|---|---|
| REST authentication through a proxy | PR.AA-01 | IA-2, AC-3 | A.8.5 |
| Restricting submission and cancellation | PR.AA-05 | AC-6, CM-7 | A.8.2 |
| Internal and REST TLS | PR.DS-02 | SC-8 | A.8.24 |
| Keytabs, keystores and connector secrets | PR.AA-01 | IA-5 | A.5.17 |
| Network exposure of port 8081 | PR.IR-01 | SC-7 | A.8.20 |
| Proxy and orchestrator logging | PR.PS-04, DE.CM-03 | AU-2, AU-12 | A.8.15 |
Common misconfigurations
- REST bound to a routable address with no proxy: a dashboard on port 8081 reachable from a wide network lets anyone who finds it submit code that runs with the cluster's credentials (ATT&CK T1190 Exploit Public-Facing Application). Bind locally and authenticate at a proxy.
- Relying on the UI flags alone: disabling
web.submit.enableonly governs the web frontend. Control the REST API. - Unpinned internal certificates: using a company CA signed certificate for internal mTLS without
security.ssl.internal.cert.fingerprintmeans any certificate from that CA is trusted. Pin the deployment certificate or use a dedicated self signed one. - One shared cluster for every team: mixing workloads of different sensitivity in one session cluster gives every job the same credential and TaskManagers. Split by Application Mode or per team clusters.
- Credentials in job code or SQL: passwords placed in JAR resources, program arguments or table DDL are visible to anyone with dashboard read access. Inject them at deploy time from a secrets store.
- Expired ticket caches in production: running long lived jobs on a
kinitcache leads to authentication failures and rushed workarounds. Use keytabs, which Flink renews automatically.
Practitioner checklist
- Every REST endpoint is bound with
rest.bind-addressto loopback or the pod interface and reachable only through an authenticating proxy. security.ssl.internal.enabledandsecurity.ssl.rest.enabled(or TLS at the proxy) are on for every cluster.- Internal certificates are dedicated to the deployment and pinned with a fingerprint when signed by a shared CA.
web.submit.enableandweb.cancel.enableare false on production session clusters, and only the pipeline identity can call submission endpoints.- Sensitive workloads run in Application Mode or dedicated clusters, with one credential set per team or trust level.
- Kerberos uses per cluster keytabs stored as read only secrets, with a rotation schedule.
- Connector secrets are injected at deploy time and never stored in JARs, arguments or SQL DDL.
- Proxy access logs, Flink logs and Kubernetes audit logs reach the SIEM, with alerts on submissions outside the pipeline.
- The history server stays on localhost or behind the proxy, and Flink security releases are applied promptly.
Standards and references
- Apache Flink: SSL Setup
- Apache Flink: Kerberos Authentication Setup and Configuration
- Apache Flink: Delegation Tokens
- Apache Flink: Configuration
- Apache Flink: Deployment overview (Application and Session Mode)
- Apache Flink: History Server
- IETF: RFC 9325 Recommendations for Secure Use of TLS and DTLS
- NIST: SP 800-53 Rev 5 Security and Privacy Controls
Related NHI Mgmt Group resources: Kafka Security Guide · Kerberos Security Guide · Kubernetes Security Guide · mTLS Guide · Service Account Security Guide