Thank you, Damian.  This concludes the vote for KIP 255.  The vote passes
with three binding + 1 votes, from Rajini, Jun, and Damian, and three
non-binding +1 votes, from Mickael, Manikumar, and myself.

I have marked the KIP as "Accepted".

The pull request is available at https://github.com/apache/kafka/pull/4994
and is squashed/rebased onto trunk.

Ron

On Mon, May 21, 2018 at 8:25 AM, Damian Guy <damian....@gmail.com> wrote:

> +1 (binding)
>
> Thanks
>
> On Mon, 21 May 2018 at 04:59 Ron Dagostino <rndg...@gmail.com> wrote:
>
> > Hi Committers.  One more binding affirmative vote is required if KIP 255
> > is to have a chance of being included in the 2.0.0 release.  Please vote
> > today.
> >
> > Ron
> >
> > > On May 18, 2018, at 9:27 PM, Ron Dagostino <rndg...@gmail.com> wrote:
> > >
> > > Hi committers.  KIP 255 still needs 1 more binding vote.  Currently
> > there are two binding + 1 votes, from Rajini and Jun, and three
> non-binding
> > +1 votes, from Mickael, Manikumar, and myself.
> > >
> > > Please vote by the Monday deadline.
> > >
> > > Ron
> > >
> > >> On Thu, May 17, 2018 at 10:59 AM, Ron Dagostino <rndg...@gmail.com>
> > wrote:
> > >> Hi Jun.  I've updated the KIP to add a new section titled "Summary for
> > Production Use" that includes this information along with a consolidated
> > set of references to the applicable specifications.  Thanks for the
> > questions.
> > >>
> > >> *We still need another binding vote* (currently there are two binding
> +
> > 1 votes, from Rajini and Jun, and three non-binding +1 votes, from
> Mickael,
> > Manikumar, and myself).
> > >>
> > >> Please vote before the May 22nd KIP Freeze deadline so this KIP can be
> > included in the 2.0.0 release.
> > >>
> > >> A pull request is available and includes additional commits reflecting
> > initial review comments: https://github.com/apache/kafka/pull/4994
> > >>
> > >> Ron
> > >>
> > >>> On Wed, May 16, 2018 at 8:09 PM, Jun Rao <j...@confluent.io> wrote:
> > >>> Hi, Ron,
> > >>>
> > >>> Thanks. I understand now. It may be useful to add a reference to JWT
> > in the
> > >>> KIP.
> > >>>
> > >>> Jun
> > >>>
> > >>> On Tue, May 15, 2018 at 6:51 PM, Ron Dagostino <rndg...@gmail.com>
> > wrote:
> > >>>
> > >>> > Hi Jun.  I think you are getting at the fact that OAuth 2 is a
> > flexible
> > >>> > framework that allows different installations to do things
> > differently.  It
> > >>> > is true that the principal name in Kafka could come from any claim
> > in the
> > >>> > token.  Most of the time it would come from the 'sub' claim, but it
> > could
> > >>> > certainly come from another claim, or it could be only indirectly
> > based on
> > >>> > a claim value (maybe certain text would be trimmed or
> > prefixed/suffixed).
> > >>> > The point, which I think you are getting at, is that because the
> > framework
> > >>> > is flexible we need to accommodate that flexibility.  The callback
> > handler
> > >>> > class defined by the listener.name.sasl_ssl.
> oauthbearer.sasl.server.
> > >>> > callback.handler.class configuration value gives us the required
> > >>> > flexibility.  As an example, I have an implementation that
> leverages
> > a
> > >>> > popular open source JOSE library to parse the compact
> serialization,
> > >>> > retrieve the public key if it has not yet been retrieved, verify
> the
> > >>> > digital signature, and map the 'sub' claim to the
> OAuthBearerToken's
> > >>> > principal name (which becomes the SASL authorization ID, which
> > becomes the
> > >>> > Kafka principal name).  I could just as easily have mapped a
> > different
> > >>> > claim to the OAuthBearerToken's principal name, manipulated the
> > 'sub' claim
> > >>> > value in some way, etc.  I write the callback handler code, so I
> > complete
> > >>> > flexibility to do whatever my OAuth 2 installation requires me to
> do.
> > >>> >
> > >>> > Ron
> > >>> >
> > >>> > On Tue, May 15, 2018 at 1:39 PM, Jun Rao <j...@confluent.io> wrote:
> > >>> >
> > >>> > > Hi, Ron,
> > >>> > >
> > >>> > > Thanks for the reply. I understood your answers to #2 and #3.
> > >>> > >
> > >>> > > For #1, will the server map all clients' principal name to the
> > value
> > >>> > > associated with "sub" claim? How do we support mapping different
> > clients
> > >>> > to
> > >>> > > different principal names?
> > >>> > >
> > >>> > > Jun
> > >>> > >
> > >>> > > On Mon, May 14, 2018 at 7:02 PM, Ron Dagostino <
> rndg...@gmail.com>
> > >>> > wrote:
> > >>> > >
> > >>> > > > Hi Jun.  Thanks for the +1 vote.
> > >>> > > >
> > >>> > > > Regarding the first question about token claims, yes, you have
> it
> > >>> > correct
> > >>> > > > about translating the OAuth token to a principle name via a
> JAAS
> > module
> > >>> > > > option in the default unsecured case.  Specifically, the OAuth
> > SASL
> > >>> > > Server
> > >>> > > > implementation is responsible for setting the authorization ID,
> > and it
> > >>> > > gets
> > >>> > > > the authorization ID from the OAuthBearerToken's
> principalName()
> > >>> > method.
> > >>> > > > The listener.name.sasl_ssl.oauthbearer.sasl.server.
> > >>> > > callback.handler.class
> > >>> > > > is responsible for handling an instance of
> > OAuthBearerValidatorCallback
> > >>> > > to
> > >>> > > > accept a token compact serialization from the client and return
> > an
> > >>> > > instance
> > >>> > > > of OAuthBearerToken (assuming the compact serialization
> > validates), and
> > >>> > > in
> > >>> > > > the default unsecured case the builtin unsecured validator
> > callback
> > >>> > > handler
> > >>> > > > defines the OAuthBearerToken.principalName() method to return
> the
> > >>> > 'sub'
> > >>> > > > claim value by default (with the actual claim it uses being
> > >>> > configurable
> > >>> > > > via the unsecuredValidatorPrincipalClaimName JAAS module
> > option).  So
> > >>> > > that
> > >>> > > > is how we translate from a token to a principal name in the
> > default
> > >>> > > > unsecured (out-of-the-box) case.
> > >>> > > >
> > >>> > > > For production use cases, the implementation associated with
> > >>> > > >
> > listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class
> > >>> > > can
> > >>> > > > do whatever it wants.  As an example, I have written a class
> that
> > >>> > wraps a
> > >>> > > > com.nimbusds.jwt.SignedJWT instance (see
> > >>> > > > https://connect2id.com/products/nimbus-jose-jwt/) and presents
> > it as
> > >>> > an
> > >>> > > > OAuthBearerToken:
> > >>> > > >
> > >>> > > > public class NimbusSignedJwtOAuthBearerToken implements
> > >>> > > OAuthBearerToken {
> > >>> > > >     private final SignedJWT signedJwt;
> > >>> > > >     private final String principalName;
> > >>> > > >     private final Set<String> scope;
> > >>> > > >     private final Long startTimeMs;
> > >>> > > >     private final long lifetimeMs;
> > >>> > > >
> > >>> > > >     /**
> > >>> > > >      * Constructor
> > >>> > > >      *
> > >>> > > >      * @param signedJwt
> > >>> > > >      *            the mandatory signed JWT
> > >>> > > >      * @param principalClaimName
> > >>> > > >      *            the mandatory claim name identifying the
> claim
> > from
> > >>> > > which
> > >>> > > > the
> > >>> > > >      *            principal name will be extracted. The claim
> > must
> > >>> > exist
> > >>> > > > and must be
> > >>> > > >      *            a String.
> > >>> > > >      * @param optionalScopeClaimName
> > >>> > > >      *            the optional claim name identifying the claim
> > from
> > >>> > > which
> > >>> > > > any scope
> > >>> > > >      *            will be extracted. If specified and the claim
> > exists
> > >>> > > then
> > >>> > > > the
> > >>> > > >      *            value must be either a String or a String
> List.
> > >>> > > >      * @throws ParseException
> > >>> > > >      *             if the principal claim does not exist or is
> > not a
> > >>> > > > String; the
> > >>> > > >      *             scope claim is neither a String nor a String
> > List;
> > >>> > the
> > >>> > > > 'exp'
> > >>> > > >      *             claim does not exist or is not a number; the
> > 'iat'
> > >>> > > claim
> > >>> > > > exists
> > >>> > > >      *             but is not a number; or the 'nbf' claim
> > exists and
> > >>> > is
> > >>> > > > not a
> > >>> > > >      *             number.
> > >>> > > >      */
> > >>> > > >     public NimbusSignedJwtOAuthBearerToken(SignedJWT
> signedJwt,
> > String
> > >>> > > > principalClaimName,
> > >>> > > >             String optionalScopeClaimName) throws
> ParseException
> > {
> > >>> > > >         // etc...
> > >>> > > >     }
> > >>> > > >
> > >>> > > > The callback handler runs the following code if the digital
> > signature
> > >>> > > > validates:
> > >>> > > >
> > >>> > > >     callback.token(new NimbusSignedJwtOAuthBearerToke
> n(signedJwt,
> > >>> > "sub",
> > >>> > > > null));
> > >>> > > >
> > >>> > > > I hope that answers the first question.  If not let me know
> what
> > I
> > >>> > > > missed/misunderstood and I'll be glad to try to address it.
> > >>> > > >
> > >>> > > > Regarding the second question, the classes
> > OAuthBearerTokenCallback and
> > >>> > > > OAuthBearerValidatorCallback implement the Callback interface
> --
> > they
> > >>> > are
> > >>> > > > the callbacks that the AuthenticateCallbackHandler
> > implementations need
> > >>> > > to
> > >>> > > > handle.  Specifically, unless the unsecured functionality is
> > what is
> > >>> > > > desired, the two configuration values [listener.name.sasl_ssl.
> > >>> > > oauthbearer.
> > >>> > > > ]sasl.login.callback.handler.class and
> > >>> > > >
> > listener.name.sasl_ssl.oauthbearer.sasl.server.callback.handler.class
> > >>> > > > define the callback handlers that need to handle
> > >>> > OAuthBearerTokenCallback
> > >>> > > > and OAuthBearerValidatorCallback, respectively.
> > >>> > > >
> > >>> > > > Regarding the third question, yes, I see your point that the
> way
> > the
> > >>> > spec
> > >>> > > > is worded could be taken to imply that the error code is a
> single
> > >>> > > > character: "A single ASCII..." (
> > >>> > > > https://tools.ietf.org/html/rfc6749#section-5.2).  However, it
> > is not
> > >>> > a
> > >>> > > > single character.  See the end of that section 5.2 for an
> > example that
> > >>> > > > shows "error":"invalid_request" as the response.
> > >>> > > >
> > >>> > > > Thanks again for the +1 vote, Jun, and please do let me know if
> > I can
> > >>> > > cover
> > >>> > > > anything else.
> > >>> > > >
> > >>> > > > Ron
> > >>> > > >
> > >>> > > >
> > >>> > > > On Mon, May 14, 2018 at 7:10 PM, Jun Rao <j...@confluent.io>
> > wrote:
> > >>> > > >
> > >>> > > > > Hi, Ron,
> > >>> > > > >
> > >>> > > > > Thanks for the KIP. +1 from me. Just a few minor comments
> > below.
> > >>> > > > >
> > >>> > > > > 1. It seems that we can translate an OAuth token to a
> > principle name
> > >>> > > > > through the claim name configured in JASS. However, it's not
> > clear to
> > >>> > > me
> > >>> > > > > how an OAuth token is mapped to a claim. Could you clarify
> > that?
> > >>> > > > >
> > >>> > > > > 2. The wiki has the following code. It seems that
> > >>> > > > OAuthBearerTokenCallback
> > >>> > > > > should implement AuthenticateCallbackHandler? Ditto
> > >>> > > > > for OAuthBearerValidatorCallback.
> > >>> > > > >
> > >>> > > > > public class OAuthBearerTokenCallback implements Callback
> > >>> > > > >
> > >>> > > > > 3. In OAuthBearerTokenCallback, we have the following method.
> > The
> > >>> > OAuth
> > >>> > > > > spec says the error code is a single ASCII. So, should we
> > return a
> > >>> > Char
> > >>> > > > or
> > >>> > > > > a String?
> > >>> > > > >
> > >>> > > > > public String errorCode()
> > >>> > > > >
> > >>> > > > > Jun
> > >>> > > > >
> > >>> > > > >
> > >>> > > > > On Thu, May 3, 2018 at 8:55 PM, Ron Dagostino <
> > rndg...@gmail.com>
> > >>> > > wrote:
> > >>> > > > >
> > >>> > > > > > Hi everyone.  I would like to start the vote for KIP-255:
> > >>> > > > > > https://cwiki.apache.org/confluence/pages/viewpage.
> > >>> > > > > action?pageId=75968876
> > >>> > > > > >
> > >>> > > > > > This KIP proposes to add the following functionality
> related
> > to
> > >>> > > > > > SASL/OAUTHBEARER:
> > >>> > > > > >
> > >>> > > > > > 1) Allow clients (both brokers when SASL/OAUTHBEARER is the
> > >>> > > > inter-broker
> > >>> > > > > > protocol as well as non-broker clients) to flexibly
> retrieve
> > an
> > >>> > > access
> > >>> > > > > > token from an OAuth 2 authorization server based on the
> > declaration
> > >>> > > of
> > >>> > > > a
> > >>> > > > > > custom login CallbackHandler implementation and have that
> > access
> > >>> > > token
> > >>> > > > > > transparently and automatically transmitted to a broker for
> > >>> > > > > authentication.
> > >>> > > > > >
> > >>> > > > > > 2) Allow brokers to flexibly validate provided access
> tokens
> > when a
> > >>> > > > > client
> > >>> > > > > > establishes a connection based on the declaration of a
> > custom SASL
> > >>> > > > Server
> > >>> > > > > > CallbackHandler implementation.
> > >>> > > > > >
> > >>> > > > > > 3) Provide implementations of the above retrieval and
> > validation
> > >>> > > > features
> > >>> > > > > > based on an unsecured JSON Web Token that function
> > out-of-the-box
> > >>> > > with
> > >>> > > > > > minimal configuration required (i.e. implementations of the
> > two
> > >>> > types
> > >>> > > > of
> > >>> > > > > > callback handlers mentioned above will be used by default
> > with no
> > >>> > > need
> > >>> > > > to
> > >>> > > > > > explicitly declare them).
> > >>> > > > > >
> > >>> > > > > > 4) Allow clients (both brokers when SASL/OAUTHBEARER is the
> > >>> > > > inter-broker
> > >>> > > > > > protocol as well as non-broker clients) to transparently
> > retrieve a
> > >>> > > new
> > >>> > > > > > access token in the background before the existing access
> > token
> > >>> > > expires
> > >>> > > > > in
> > >>> > > > > > case the client has to open new connections.
> > >>> > > > > >
> > >>> > > > > > Thanks,
> > >>> > > > > >
> > >>> > > > > > Ron
> > >>> > > > > >
> > >>> > > > >
> > >>> > > >
> > >>> > >
> > >>> >
> > >>
> > >
> >
>

Reply via email to