Security
import { Kafka } from '@cookiemonsterdev/kafka-core';
const kafka = new Kafka({
clientId: 'my-app',
brokers: ['localhost:9093'],
ssl: true,
sasl: { mechanism: 'plain', username: 'alice', password: 'secret' },
});
ssl: true uses Node TLS defaults. Pass a tls.ConnectionOptions object for
certs. See
SSL
and
SASL.
Source:
types/index.ts
(KafkaConfig.ssl / sasl).
SASL
mechanism |
Notes |
|---|---|
plain |
Username and password |
scram-sha-256 |
SCRAM, or delegation token via tokenId / tokenHmac |
scram-sha-512 |
SCRAM, or delegation token via tokenId / tokenHmac |
oauthbearer |
Token provider |
gssapi |
Kerberos; gssProvider or optional kerberos package |
| custom provider | { mechanism, authenticationProvider } |
aws is an extra (non-Apache) helper. Failed SASL throws
KafkaSASLAuthenticationError (non-retriable). See
Errors.
GSSAPI / Kerberos
Opt-in. Handshake mechanism name is GSSAPI. serviceName defaults to
kafka (broker property sasl.kerberos.service.name). The broker must
advertise GSSAPI and you need a reachable KDC plus a ticket or keytab.
const kafka = new Kafka({
clientId: 'my-app',
brokers: ['broker.example.com:9093'],
ssl: true,
sasl: {
mechanism: 'gssapi',
serviceName: 'kafka',
principal: 'alice@EXAMPLE.COM',
keytab: '/etc/security/keytabs/alice.keytab',
krb5: '/etc/krb5.conf',
},
});
Without gssProvider, the client loads the optional kerberos
package (>=7, Node 20+ prebuilds including Node 24) and runs GSS token
exchange plus RFC 4752 wrap. Install it next to the client:
npm install kerberos
keytab / krb5 are applied as KRB5_CLIENT_KTNAME / KRB5_KTNAME and
KRB5_CONFIG for the duration of each GSS round (process-wide; do not run
concurrent GSSAPI clients with different keytabs in one process). You can
instead kinit and omit those fields.
To drive tokens yourself (another binding, or tokens from kinit + a GSS
library):
sasl: {
mechanism: 'gssapi',
serviceName: 'kafka',
gssProvider: async ({ serverToken, host, serviceName }) => {
// Return the next client GSS token. Set complete after the last send
// (including the RFC 4752 wrap of the authorization identity).
return { token: nextToken(serverToken, host, serviceName), complete: false };
},
}
CI does not run a Kerberos KDC. Unit tests mock the token exchange. A manual
harness is: MIT krb5 KDC + Kafka sasl.enabled.mechanisms=GSSAPI + a client
principal/keytab, then kinit (or keytab / krb5 as above) and connect.
Delegation tokens
Admin createDelegationToken / describeDelegationToken /
renewDelegationToken / expireDelegationToken talk to the controller
(keys 38–41). The broker must set delegation.token.secret.key and the
client must use SASL — not PLAINTEXT or one-way SSL, or the broker returns
DELEGATION_TOKEN_REQUEST_NOT_ALLOWED / DELEGATION_TOKEN_AUTH_DISABLED.
Default test compose files do not enable tokens.
Logging in with a minted token piggybacks on SASL/SCRAM (not a separate
TOKEN mechanism). tokenId is the SCRAM username, tokenHmac is the
password (a Buffer from Admin is encoded as standard base64), and the
client-first message includes tokenauth=true so the broker looks up the
token instead of a stored SCRAM user. The handshake mechanism stays
SCRAM-SHA-256 or SCRAM-SHA-512. The broker must enable that SCRAM
mechanism and delegation.token.secret.key. See
SASL authentication.
const adminKafka = new Kafka({
brokers: ['localhost:9093'],
ssl: true,
sasl: { mechanism: 'scram-sha-256', username: 'alice', password: 'alice-secret' },
});
const admin = adminKafka.admin();
await admin.connect();
const token = await admin.createDelegationToken();
await admin.disconnect();
const worker = new Kafka({
brokers: ['localhost:9093'],
ssl: true,
sasl: {
mechanism: 'scram-sha-256',
tokenId: token.tokenId,
tokenHmac: token.hmac,
},
});
const producer = worker.producer();
await producer.connect();