Table of Contents |
---|
Status
Current state: ["DISCUSSION"]. Accepted
Discussion thread: here
JIRA: KAFKA-1696
...
getDelegationToken(request: DelegationTokenRequestCreateDelegationTokenRequest): CreateDelegationTokenResponse
class DelegationTokenRequestCreateDelegationTokenRequest(renewer: Set[KafkaPrincipal] = Set.empty, maxLifeTime: long = -1)
class DelegationTokenResponseCreateDelegationTokenResponse(ownerissueTimeMillis: KafkaPrincipallong, expiryTimeMillisexpiryTimeMillis: long, renewer: Set[KafkaPrincipal], maxLifeTime: maxLifeTime: long, tokenId: String, hmac: byte[])
renewDelegationToken(request: RenewDelegationTokenRequest): DelegationTokenResponseRenewDelegationTokenResponse
class RenewDelegationTokenRequest(hmac: byte[], expiryTimeMillis: long)
expireToken(request: ExpireTokenRequestExpireDelegationTokenRequest): ExpireDelegationTokenResponse
class ExpireTokenRequestExpireDelegationTokenRequest(hmac: byte[], expireAt: long = Systemtime.currentTimeMillis)
Protocol changes
DelegationTokenRequest
describeToken(request: DescribeDelegationTokenRequest): DescribeDelegationTokenResponse
class DescribeDelegationTokenRequest(owner: Set[KafkaPrincipal] )
Protocol changes
CreateDelegationTokenRequest
Code Block |
---|
CreateDelegationTokenRequest |
Code Block |
DelegationTokenRequest => [Renewer] MaxDateMs
Renewer => string
MaxDateMs => INT64 |
Field | Description |
---|---|
Renewer | Renewer is an Kafka PrincipalType+name string, who is allowed to renew this token before the max lifetime expires. If Renewer list is empty, then Renewer will default to the owner (Principal which requested this token). |
MaxDateMs | Max lifetime for the token in milliseconds. if If the value is -1, then MaxLifeTime will default to a server side config value (delegation.token. |
DelegationTokenResponse
max.lifetime.ms). |
CreateDelegationTokenResponse
Code Block |
---|
DelegationTokenResponseCreateDelegationTokenResponse => ErrorCode TokenDetails ErrorCode => INT16 TokenDetails => IssueDateMs ExpiryDateMs MaxDateMs TokenId HMAC IssueDateMs => INT64 ExpiryDateMs => INT64 MaxDateMs => INT64 TokenId => String HMAC => bytes |
Field | Description | ||
---|---|---|---|
IssueDateMs | timestamp (in msec) when this token was generated. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). ExpiryDateMs | ||
MaxDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). | ||
ExpiryDateMs | max life timestamp (in msec) of this token. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). | ||
TokenId | Sequence number to ensure | TokenId | Sequence number to ensure uniqueness |
HMAC | Keyed-hash message authentication code |
...
Field | Description |
---|---|
HMAC | HMAC of the delegation token to be renewed |
RenewPeriodMs | Renew Time period in milli seconds |
RenewDelegationTokenResponse
milliseconds. If the value is -1, then Renew Time period will default to a server side config value (delegation.token.expiry.time.ms). |
RenewDelegationTokenResponse
Code Block |
---|
RenewDelegationTokenResponse => |
Code Block |
RenewDelegationTokenResponse => ErrorCode
ErrorCode => INT32
ExpiryDateMs => INT64 |
Field | Description |
---|---|
ErrorCode | |
ExpiryDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds sincebeginning since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
Possible Error Codes
Field | Description |
---|---|
ErrorCode | |
ExpiryDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds since beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
* DelegationTokenDisabledException
* TokenRenewerMismatchException
* TokenNotFoundException
ExpireDelegationTokenRequest
Code Block |
---|
ExpireDelegationTokenRequest => |
Possible Error Codes
* DelegationTokenDisabledException
* TokenRenewerMismatchException
* TokenNotFoundException
ExpireTokenRequest
Code Block |
---|
ExpireTokenRequest => HMAC expiryDateMs
HMAC => bytes
ExpiryDateMs => INT64 |
Field | Description |
---|---|
HMAC | HMAC of the delegation token to be renewed |
ExpiryDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds since beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
...
Expiry time period in milliseconds. If the value is -1, then the token will get invalidated immediately. |
ExpireDelegationTokenResponse
Code Block |
---|
ExpireDelegationTokenResponse |
Code Block |
ExpireTokenResponse => ErrorCode
ErroCode => INT32
ExpiryDateMs => INT64 |
Field | Description |
---|---|
ErrorCode | |
ExpiryDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds sincebeginning since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
Field | Description |
ErrorCode | |
ExpiryDateMs | timestamp (in msec) at which this token expires.Unit is milliseconds since beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
Possible Error Codes
* DelegationTokenDisabledException
-1 value will invalidate the token immediately |
Possible Error Codes
* DelegationTokenDisabledException
* * TokenRenewerMismatchException
* TokenNotFoundException
DescribeTokenRequest
DescribeDelegationTokenRequest
Code Block |
---|
DescribeTokenRequestDescribeDelegationTokenRequest => [Owner] Owner => String |
Field | Description |
---|---|
ErrorCode | |
Owner | Kakfa Principal which requested the delegation token |
Field | Description |
ErrorCode | |
Owner | Kakfa Principal which requested the delegation token. If the Owner list . If the Owner list is null (i.e., length is -1), the response contains all the allowed tokens from all owners |
...
. If Owner list is empty, the response is empty list. |
DescribeDelegationTokenResponse
Code Block |
---|
DescribeTokenResponseDescribeDelegationTokenResponse => ErrorCode [TokenDetails] ErrorCode => INT16 TokenDetails => Owner IssueDateMs ExpiryDateMs TokenId HMAC [Renewer] Owner => String IssueDateMs => INT64 ExpiryDateMs => INT64 MaxDateMs => INT64 TokenId => String HMAC => bytes Renewer => String |
Field | Description | ||
---|---|---|---|
Owner | Kakfa Principal which requested the delegation token | ||
IssueDateMs | timestamp (in msec) when this token was generated. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). ExpiryDateMs | ||
MaxDateMs | max life timestamp (in msec) | at whichof this token | expires. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). |
ExpiryDateMs | timestamp (in msec) at which this token expires. Unit is milliseconds since the beginning of the epoch (midnight Jan 1, 1970 (UTC)). | ||
TokenId | TokenId | Sequence number to ensure uniqueness | |
HMAC | Keyed-hash message authentication code | ||
Renewer | Renewers list |
Possible Error Codes
* DelegationTokenDisabledException
...
delegation.token.max.lifetime.ms : The token has a maximum lifetime beyond which it cannot be renewed any moreanymore. Default value 7 days.
delegation.token.expiry.time.ms : The token validity time in seconds before the token needs to be renewed. Default value 1 day.
delegation.token.master.key : masterKey/secret to generate and verify delegation tokens. This masterKey/secret needs secret needs to be configured with all the brokers. Same secret key must be configured across all the brokers. If If the masterKey/secret is not set or set to empty string, brokers will disable the delegation token support.
...
TokenDetails:
- Owner ID -- Username that this token will authenticate as
- Renewers ID -- designated renewers list
- Issue date -- timestamp (in msec) when this token was generated
- Expiry date -- timestamp (in msec) at which this token expires
- Max Date - max life timestamp (in msec) of this token.
- TokenID – UUID to TokenID -- Sequence number to ensure uniqueness
TokenAuthenticator(HMAC) := HMAC_SHA1(master key, TokenID)
Authentication Token := (TokenDetails, TokenAuthenticator(HMAC))
...
The MasterKey/secret is used to generate and verify delegation tokens. This is supplied using config option. This Same secret needs to key must be configured with across all the brokers. The current proposal does not support rotation of secret. If If the secret is not set or set to empty string, brokers will disable the delegation token support. The current proposal does not support rotation of secret. We require
Procedure to manually rotate the secret:
We require a re-deployment when the secret needs to be rotated. During this process, already connected clients will continue to work. But any new connection requests and renew/expire requests with old tokens can fail.
- expire all existing tokens
- rotate the secret by rolling upgrade, and
- generate new tokens
Token Token acquisition
Following steps describe how tokens can be acquired:
...
SCRAM is a suitable mechanism for authentication using delegation tokens. KIP-84 proposes to support SASL SCRAM mechanisms. Kafka clients can authenticate using SCRAM-SHA-256, providing the delegation token HMAC as password.
Server will look up the token from its token cache, if it finds a match and token is not expired it will authenticate the client and the identity will be established as the owner of the delegation token.
If the token is not matched or token is expired, broker throws appropriate exception back and does not allow the client to continue.
Token renewal
The (Admin/Delegation Token) client authenticates using Kerberos or any other available authentication scheme. A token can not be renewed if the initial authentication is done through delegation token, client must use a different auth scheme.
Client sends a request to renew a token with an optional renew life time which must be < max life time of token.
Broker looks up the token, if token is expired or if the renewer’s identity does not match with the token’s renewers, or if token renewal is beyond the Max life time of token, broker disallows the operation by throwing an appropriate exception.
If none of the above conditions are matched, broker updates token’s expiry. Note that the HMAC-SASM is unchanged so the token on client side is unchanged. Broker updates the expiration in its local cache and on zookeeper so other brokers also get notified and their cache statuses are updated as well.
Token expiration and cancellation
...
Token is stored in Zookeeper as properties in the path /tokenauthdelegation_token/tokens/<tokenUID>. S During server startup and token creation, scram credentials are generated during token creation. We will use password=HMAC, iterations=4096 for scram credential generation.and stored in memory (TokenCache).
Code Block | ||||
---|---|---|---|---|
| ||||
//Delegation Token Details for tokenID token123: Zookeeper persistence path /tokenauth/tokens/token123 { "version":1, "owner" : "owner", "renewer" : "renewer", "issueDateissueTimestamp" : "issueDateissueTimestamp", "tokenIDmaxTimestamp" : "sequence-numbermaxTimestamp", //Store SCRAM credentials as per KIP-84 "expiryTimestamp" : "expiryTimestamp", "credentialstokenID" : { "SCRAM-SHA-512" : "salt=djR5dXdtZGNqamVpeml6NGhiZmMwY3hrbg==,stored_key=sb5jkqStV9RwPVTGxG1ZJHxF89bqjsD1jT4S...==,server_key=...,iterations=4096", "SCRAM-SHA-256" : "salt=10ibs0z7xzlu6w5ns0n188sis5,stored_key=+Acl/wi1vLZ95Uqj8rRHVcSp6qrdfQIwZbaZBwM0yvo=,server_key=nN+fZauE6vG0hmFAEj/49+2yk0803y67WSXMYkgh77k=,iterations=4096" } }; |
SCRAM Extensions
SCRAM messages have an optional extensions field which is a comma-separated list of key=value pairs.
After KIP-84 implementation , an extension will be added to the first client SCRAM message to indicate
that authentication is being requested for a delegation token. This will enable Kafka broker to obtain
credentials and principal using a different code path for delegation tokens.
JAAS configuration
Code Block | ||||
---|---|---|---|---|
| ||||
KafkaClient {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="test123"
password="ab24267ac3e827e00e57cdf98465baccecbbeced512e90a719026177e04e547e";
tokenauth=true
}; |
DelegationToken Client
We will be providing a DelegationToken Client using which users can generate, renew and expire the tokens. This may part of AdminClient implementation (KIP-4).
"UUID",
}; |
SCRAM Extensions
SCRAM messages have an optional extensions field which is a comma-separated list of key=value pairs.
After KIP-84 implementation , an extension will be added to the first client SCRAM message to indicate
that authentication is being requested for a delegation token. This will enable Kafka broker to obtain
credentials and principal using a different code path for delegation tokens.
JAAS configuration
Code Block | ||||
---|---|---|---|---|
| ||||
KafkaClient {
org.apache.kafka.common.security.scram.ScramLoginModule required
username="test123"
password="ab24267ac3e827e00e57cdf98465baccecbbeced512e90a719026177e04e547e";
tokenauth=true
}; |
DelegationToken Client
We will be providing a DelegationToken Client using which users can generate, renew and expire the tokens. This may part of AdminClient implementation (KIP-4).
Code Block | ||||
---|---|---|---|---|
| ||||
public class DelegationTokenClient {
public TokenDetails generateToken(List<String> renewers, long maxLifeTime);
public boolean renewToken(bytes[] hmac, long renewPeriod);
public boolean expireToken(bytes[] hmac, long expireTimeStamp); | ||||
Code Block | ||||
| ||||
public class DelegationTokenClient { public TokenDetailsboolean generateToken(List<String> renewers, long maxLifeTime); public boolean renewToken(bytesinvalidateToken(bytes[] hmac, long renewPeriod); public booleanList<TokenDetails> expireToken(bytes[] hmac, long expireTimeStampdescribeTokens(); public booleanvoid invalidateTokenclose(bytes[] hmac); public List<TokenDetails> describeTokens(); public void close(); } |
Command line tool
We will provide a CLI to acquire delegation tokens, renew tokens and to invalidate/expire tokens.
Changes to Java Clients (producer/consumer)
KIP-85 allows dynamic JAAS configuration for Kafka clients. After this we can easily configure the
delegation token for SCRAM-SHA-256 authentication.
Below diagram shows the steps required to use the delegation tokens.
...
} |
Command line tool
We will provide a commandline script to acquire delegation tokens, renew tokens, invalidate/expire and to describe tokens.
bin/kafka-delegation-token.sh --bootstrap-server broker1:9092 --create --renewer renewer1,renewer2 --max-life-time 1486750745585
bin/kafka-delegation-token.sh --bootstrap-server broker1:9092 --renew --hmac hmacString --renew-time-period 50745585
bin/kafka-delegation-token.sh --bootstrap-server broker1:9092 --expire --hmac hmacString --expiry-time-period 50745585
bin/kafka-delegation-token.sh --bootstrap-server broker1:9092 --describe --owner owner1,owner2
Changes to Java Clients (producer/consumer)
KIP-85 allows dynamic JAAS configuration for Kafka clients. After this we can easily configure the
delegation token for SCRAM-SHA-256 authentication.
Below diagram shows the steps required to use the delegation tokens.
ACL
Currently, we only allow a user to create delegation token for that user only. Renew and expire requests should come from owner or renewers of the token. So we don't need ACLs for create/renew/expire requests.
Owners and the renewers can always describe their own tokens. To describe others tokens, we can add DESCRIBE operation on Token Resource. In future, when we extend the support to allow a user to acquire delegation tokens for other users, then we can enable CREATE/DELETE operations.
Operation | Resource | API |
---|---|---|
DESCRIBE | Token | describeTokens |
CREATE | Token | createToken (Will be introduced in a future release) |
DELETE | Token | deleteToken (Will be introduced in a future release) |
Q/A
Q1. Is there any dependency on Hadoop APIs/Libraries?
...