Minor correction: I'm proposing "connections.max.reauth.ms" as the
broker-side configuration property, not "
connections.max.expired.credentials.ms".

Ron

On Fri, Sep 14, 2018 at 8:40 PM Ron Dagostino <rndg...@gmail.com> wrote:

> Hi Rajini.  I'm going to choose *connections.max.expired.credentials.ms
> <http://connections.max.expired.credentials.ms>* as the option name
> because it is consistent with the comment I made in the section about how
> to get the client and server to agree on credential lifetime:
>
> "We could add a new API call so that clients could ask servers for the
> lifetime they use, or we could extend the SaslHandshakeRequest/Response API
> call to include that information in the server's response – the client
> would then adopt that value"
>
>
> We set the config option value on the broker (with the "
> listener.name.mechanism." prefix), and we will return the configured
> value in the SaslHandshakeResponse (requiring a wire format change in
> addition to a version bump).  The value (referred to as "X" below) can be
> negative, zero, or positive and is to be interpreted as follows:
>
> X = 0: Fully disable.  The server will respond to re-authentications, but
> it won't kill any connections due to expiration, and it won't track either
> of the 2 metrics mentioned below.
>
> Now, a couple of definitions for when X != 0:
>
> 1) We define the *maximum allowed expiration time* to be the time
> determined by the point when (re-)authentication occurs plus |X|
> milliseconds.
> 2) We define the *requested expiration time* to be the maximum allowed
> expiration time except for the case of an OAuth bearer token, in which case
> it is the point at which the token expires.  (Kerberos presumably also
> specifies a ticket lifetime, but frankly I am not in a position to do any
> Kerberos-related coding in time for a 2.1.0 release and would prefer to
> ignore this piece of information for this KIP -- would it be acceptable to
> have someone else add it later?).
>
> Based on these definitions, we define the behavior as follows:
>
> *X > 0: Fully enable*
> A) The server will reject any authentication/re-authentication attempt
> when the requested expiration time is after the maximum allowed expiration
> time (which could only happen with an OAuth bearer token, assuming we skip
> dealing with Kerberos for now).
> B) The server will kill connections that are used beyond the requested
> expiration time.
> C) A broker metric will be maintained that documents the number
> connections killed by the broker.  This metric will be non-zero if a client
> is connecting to the broker with re-authentication either unavailable (i.e.
> an older client) or disabled.
>
> *X < 0: Partially enable*
> A) Same as above: the server will reject any
> authentication/re-authentication attempt when the requested expiration time
> is after the maximum allowed expiration time (which could only happen with
> an OAuth bearer token, assuming we skip dealing with Kerberos for now).
> B) The server will **not** kill connections that are used beyond the
> requested expiration time.
> C) A broker metric will be maintained that documents the number of API
> requests unrelated to re-authentication that are made over a connection
> beyond the requested expiration time.  This metric will be helpful for
> operators to ensure that all clients are properly upgraded and
> re-authenticating before fully enabling the server-side
> expired-connection-kill functionality (i.e. by changing the value from a
> negative number to a positive number): this metric will be zero across all
> brokers when it is safe to fully enable the server-side feature.
>
> Thoughts?
>
> Ron
>
> On Fri, Sep 14, 2018 at 11:59 AM Rajini Sivaram <rajinisiva...@gmail.com>
> wrote:
>
>> It will be good to shorten the config name. We have a config named `
>> connections.max.idle.ms`. We could add something like `
>> connections.max.expired.credentials.ms`. As you said, it would be
>> prefixed
>> with listener and SASL mechanism name. We should be able to support
>> connection termination in future even with SSL, so perhaps we don't want
>> the `sasl.server.` prefix (we just need to validate whether the config is
>> supported for the protocol). You can choose whether a boolean flag or a
>> time interval makes more sense.
>>
>> For the client-side, the KIP explains how to make it work for other
>> mechanisms and we can leave it that. Not convinced about server-side
>> though. It seems to me that we probably would require API changes to make
>> it work. Basically the proposed approach works only for OAUTHBEARER. Since
>> we have to bump up SaslHandshakeRequest version in this KIP, it will be
>> good to work out if we need to change the request or flow to make this
>> work
>> for other mechanisms. I haven't figured out exactly what is needed, but
>> will think about it and get back next week. In the meantime, you can get
>> the KIP up-to-date with the config, migration path etc. and get it ready
>> to
>> start vote next week.
>>
>>
>>
>>
>>
>> On Fri, Sep 14, 2018 at 1:24 PM, Ron Dagostino <rndg...@gmail.com> wrote:
>>
>> > Hi Rajini.
>> >
>> > Agreed, we will bump the SaslHandshakeRequest API number (no wire format
>> > change, of course).
>> >
>> > Agreed, responding to re-authentication will always be enabled on the
>> > broker since it is initiated by the client.
>> >
>> > Agreed, connection termination by the broker will be opt-in.  I'm
>> thinking
>> > *sasl.server.disconnect.expired.credential.connections.enable*, prefixed
>> > with listener and SASL mechanism name in lower-case so it can be opt-in
>> at
>> > the granularity of a SASL mechanism; for example, "
>> > listener.name.sasl_ssl.oauthbearer.sasl.server.
>> > disconnect.expired.credential.connections.enable=true
>> > ".  It is long, so if you have a preference for a shorter name let me
>> know
>> > and we'll go with it instead.
>> >
>> > Agreed, additional metrics will be helpful.  I'll add them to the KIP.
>> >
>> > <<<need to work out exactly how this works with all SASL mechanisms
>> > <<<not sure we have the data required on the broker or a way of
>> > <<< extending the [GSSAPI] mechanism
>> > Not sure I agree here.  The paragraph I added to the KIP describes how I
>> > think this can be done.  Given that description, do you still feel
>> Kerberos
>> > will not be possible?  If Kerberos presents a significant hurdle then I
>> > don't think that should prevent us from doing it for other mechanisms
>> -- I
>> > would rather state that it isn't supported with GSSAPI due to
>> limitations
>> > in Kerberos itself than not have it for OAUTHBEARER, for example.  And
>> > right now I don't think we need more than a high-level description of
>> how
>> > this could be done.  In other words, I think we have this covered,
>> unless
>> > there is a fundamental problem due to Kerberos not making data (i.e.
>> ticket
>> > expiration) available on the server.   I want to submit this KIP for a
>> vote
>> > early next week in the hope of having it accepted by the Monday, 9/24
>> > deadline for the 2.1.0 release, and if that happens I believe I can get
>> a
>> > PR into really good shape soon thereafter (I'm working on it now).
>> >
>> > Ron
>> >
>> >
>> >
>> >
>> >
>> >
>> > On Fri, Sep 14, 2018 at 5:57 AM Rajini Sivaram <rajinisiva...@gmail.com
>> >
>> > wrote:
>> >
>> > > Hi Ron,
>> > >
>> > > 1) Yes, we should update the version of `SaslHandshakeRequest`.
>> Clients
>> > > would attempt to re-authenticate only if broker's SaslHandshakeRequest
>> > > version >=2.
>> > > 2) I think we should enable broker's re-authentication and connection
>> > > termination code regardless of client version. Re-authentication
>> could be
>> > > always enabled since it is triggered only by clients and broker could
>> > just
>> > > handle it. Connection termination should be opt-in, but should work
>> with
>> > > clients of any version. If turned on and clients are of an older
>> version,
>> > > this would simply force reconnection, which should be ok. Additional
>> > > metrics to monitor expired connections may be useful anyway.
>> > >
>> > > We also need to work out exactly how this works with all SASL
>> mechanisms.
>> > > In particular, we have ensure that we can make it work with Kerberos
>> > since
>> > > we use the implementation from the JRE and I am not sure we have the
>> data
>> > > required on the broker or a way of extending the mechanism.
>> > >
>> > > Thoughts?
>> > >
>> > > On Thu, Sep 13, 2018 at 6:56 PM, Ron Dagostino <rndg...@gmail.com>
>> > wrote:
>> > >
>> > > > Hi Rajini.  I'm thinking about how we deal with migration.   For
>> > example,
>> > > > let's say we have an existing 2.0.0 cluster using SASL/OAUTHBEARER
>> and
>> > we
>> > > > want to use this feature.  The desired end state is to have all
>> clients
>> > > and
>> > > > brokers migrated to a version that supports the feature (call it
>> 2.x)
>> > > with
>> > > > the feature turned on.  We need to document the supported path(s) to
>> > this
>> > > > end state.
>> > > >
>> > > > Here are a couple of scenarios with implications:
>> > > >
>> > > > 1) *Migrate client to 2.x and turn the feature on but broker is
>> still
>> > at
>> > > > 2.0.*  In this case the client is going to get an error when it
>> sends
>> > the
>> > > > SaslHandshakeRequest.  We want to avoid this.  It seems to me the
>> > client
>> > > > needs to know if the broker has been upgraded to the necessary
>> version
>> > > > before trying to re-authenticate, which makes me believe we need to
>> > bump
>> > > > the API version number in 2.x and the client has to check to see if
>> the
>> > > max
>> > > > version the broker supports meets a minimum standard before trying
>> to
>> > > > re-authenticate.  Do you agree?
>> > > >
>> > > > 2) *Migrate broker to 2.x and turn the feature on but client is
>> still
>> > at
>> > > > 2.0*.  In this case the broker is going to end up killing
>> connections
>> > > > periodically.   Again, we want to avoid this.  It's tempting to say
>> > > "don't
>> > > > do this" but I wonder if we can require installations to upgrade all
>> > > > clients before turning the feature on at the brokers.  Certainly we
>> can
>> > > say
>> > > > "don't do this" for inter-broker clients -- in other words, we can
>> say
>> > > that
>> > > > all brokers in a cluster should be upgraded before the feature is
>> > turned
>> > > on
>> > > > for any one of them -- but I don't know about our ability to say it
>> for
>> > > > non-broker clients.
>> > > >
>> > > > Now we consider the cases where both the brokers and the clients
>> have
>> > > been
>> > > > upgraded to 2.x.  When and where should the feature be turned on?
>> The
>> > > > inter-broker case is interesting because I don't think think we can
>> > > require
>> > > > installations to restart every broker with a new config where the
>> > feature
>> > > > is turned on at the same time.  Do you agree that we cannot require
>> > this
>> > > > and therefore must support installations restarting brokers with a
>> new
>> > > > config at whatever pace they need -- which may be quite slow
>> relative
>> > to
>> > > > token lifetimes?  Assuming you do agree, then there is going to be
>> the
>> > > case
>> > > > where some brokers are going to have the feature turned on and some
>> > > clients
>> > > > (definitely inter-broker clients at a minimum) are going to have the
>> > > > feature turned off.
>> > > >
>> > > > The above discussion assumes a single config on the broker side that
>> > > turns
>> > > > on both the inter-broker client re-authentication feature as well as
>> > the
>> > > > server-side expired-connection-kill feature, but now I'm thinking we
>> > need
>> > > > the ability to turn these features on independently, plus maybe we
>> > need a
>> > > > way to monitor the number of "active, expired" connections to the
>> > server
>> > > so
>> > > > that operators can be sure that all clients have been
>> upgraded/enabled
>> > > > before turning on the server-side expired-connection-kill feature.
>> > > >
>> > > > So the migration plan would be as follows:
>> > > >
>> > > > 1) Upgrade all brokers to 2.x.
>> > > > 2) After all brokers are upgraded, turn on re-authentication for all
>> > > > brokers at whatever rate is desired -- just eventually, at some
>> point,
>> > > get
>> > > > the client-side feature turned on for all brokers so that
>> inter-broker
>> > > > connections are re-authenticating.
>> > > > 3) In parallel with (1) and (2) above, upgrade clients to 2.x and
>> turn
>> > > > their re-authentication feature on.  Clients will check the API
>> version
>> > > and
>> > > > only re-authenticate to a broker that has also been upgraded (note
>> that
>> > > the
>> > > > ability of a broker to respond to a re-authentication cannot be
>> turned
>> > > off
>> > > > -- it is always on beginning with version 2.x, and it just sits
>> there
>> > > doing
>> > > > nothing if it isn't exercised by an enabled client)
>> > > > 4) After (1), (2), and (3) are complete, check the 2.x broker
>> metrics
>> > to
>> > > > confirm that there are no "active, expired" connections.  Once you
>> are
>> > > > satisfied that (1), (2), and (3) are indeed complete you can enable
>> the
>> > > > server-side expired-connection-kill feature on each broker via a
>> > restart
>> > > at
>> > > > whatever pace is desired.
>> > > >
>> > > > Comments?
>> > > >
>> > > > Ron
>> > > >
>> > > >
>> > > > On Wed, Sep 12, 2018 at 4:48 PM Ron Dagostino <rndg...@gmail.com>
>> > wrote:
>> > > >
>> > > > > Ok, I am tempted to just say we go with the low-level approach
>> since
>> > it
>> > > > is
>> > > > > the quickest and seems to meet the clear requirements. We can
>> always
>> > > > adjust
>> > > > > later if we get to clarity on other requirements or we decide we
>> need
>> > > to
>> > > > > approach it differently for whatever reason.  But in the meantime,
>> > > before
>> > > > > fully committing to this decision, I would appreciate another
>> > > perspective
>> > > > > if someone has one.
>> > > > >
>> > > > > Ron
>> > > > >
>> > > > > On Wed, Sep 12, 2018 at 3:15 PM Rajini Sivaram <
>> > > rajinisiva...@gmail.com>
>> > > > > wrote:
>> > > > >
>> > > > >> Hi Ron,
>> > > > >>
>> > > > >> Yes, I would leave out retries from this KIP for now. In the
>> future,
>> > > if
>> > > > >> there is a requirement for supporting retries, we can consider
>> it. I
>> > > > think
>> > > > >> we can support retries with either approach if we needed to, but
>> it
>> > > > would
>> > > > >> be better to do it along with other changes required to support
>> > > > >> authentication servers that are not highly available.
>> > > > >>
>> > > > >> For maintainability, I am biased, so it will be good to get the
>> > > > >> perspective
>> > > > >> of others in the community :-)
>> > > > >>
>> > > > >> On Wed, Sep 12, 2018 at 7:47 PM, Ron Dagostino <
>> rndg...@gmail.com>
>> > > > wrote:
>> > > > >>
>> > > > >> > Hi Rajini.  Here is some feedback/some things I thought of.
>> > > > >> >
>> > > > >> > First, I just realized that from a timing perspective that I am
>> > not
>> > > > sure
>> > > > >> > retry is going to be necessary.  The background login refresh
>> > thread
>> > > > >> > triggers re-authentication when it refreshes the client's
>> > > credential.
>> > > > >> The
>> > > > >> > OAuth infrastructure has to be available in order for this
>> refresh
>> > > to
>> > > > >> > succeed (the background thread repeatedly retries if it can't
>> > > refresh
>> > > > >> the
>> > > > >> > credential, and that retry loop handles any temporary
>> outage).  If
>> > > > >> clients
>> > > > >> > are told to re-authenticate when the credential is refreshed
>> **and
>> > > > they
>> > > > >> > actually re-authenticate at that point** then it is highly
>> > unlikely
>> > > > that
>> > > > >> > the OAuth infrastructure would fail within those intervening
>> > > > >> milliseconds.
>> > > > >> > So we don't need re-authentication retry in this KIP as long as
>> > > retry
>> > > > >> > starts immediately.  The low-level prototype as currently coded
>> > > > doesn't
>> > > > >> > actually start re-authentication until the connection is
>> > > subsequently
>> > > > >> used,
>> > > > >> > and that could take a while.  But then again, if the connection
>> > > isn't
>> > > > >> used
>> > > > >> > for some period of time, then the lost value of having to
>> abandon
>> > > the
>> > > > >> > connection is lessened anyway.  Plus, as you pointed out, OAuth
>> > > > >> > infrastructure is assumed to be highly available.
>> > > > >> >
>> > > > >> > Does this makes sense, and would you be willing to say that
>> retry
>> > > > isn't
>> > > > >> a
>> > > > >> > necessary requirement?  I'm tempted but would like to hear your
>> > > > >> perspective
>> > > > >> > first.
>> > > > >> >
>> > > > >> > Interleaving/latency and maintainability (more than lines of
>> code)
>> > > are
>> > > > >> the
>> > > > >> > two remaining areas of comparison.  I did not add the
>> > > maintainability
>> > > > >> issue
>> > > > >> > to the KIP yet, but before I do I thought I would address it
>> here
>> > > > first
>> > > > >> to
>> > > > >> > see if we can come to consensus on it because I'm not sure I
>> see
>> > the
>> > > > >> > high-level approach as being hard to maintain (yet -- I could
>> be
>> > > > >> > convinced/convince myself; we'll see).  I do want to make sure
>> we
>> > > are
>> > > > on
>> > > > >> > the same page about what is required to add re-authentication
>> > > support
>> > > > in
>> > > > >> > the high-level case.  Granted, the amount is zero in the
>> low-level
>> > > > case,
>> > > > >> > and it doesn't get any better that that, but the amount in the
>> > > > >> high-level
>> > > > >> > case is very low -- just a few lines of code.  For example:
>> > > > >> >
>> > > > >> > KafkaAdminClient:
>> > > > >> > https://github.com/apache/kafka/pull/5582/commits/4fa70f38b9
>> > > > >> > d33428ff98b64a3a2bd668f5f28c38#diff-
>> > 6869b8fccf6b098cbcb0676e8ceb26a7
>> > > > >> > It is the same few lines of code for KafkaConsumer,
>> KafkaProducer,
>> > > > >> > WorkerGroupMember, and TransactionMarkerChannelManager
>> > > > >> >
>> > > > >> > The two synchronous I/O use cases are ControllerChannelManager
>> and
>> > > > >> > ReplicaFetcherBlockingSend (via ReplicaFetcherThread), and they
>> > > > require
>> > > > >> a
>> > > > >> > little bit more -- but not much.
>> > > > >> >
>> > > > >> > Thoughts?
>> > > > >> >
>> > > > >> > Ron
>> > > > >> >
>> > > > >> > On Wed, Sep 12, 2018 at 1:57 PM Ron Dagostino <
>> rndg...@gmail.com>
>> > > > >> wrote:
>> > > > >> >
>> > > > >> > > Thanks, Rajini.  Before I digest/respond to that, here's an
>> > update
>> > > > >> that I
>> > > > >> > > just completed.
>> > > > >> > >
>> > > > >> > > I added a commit to the PR (
>> > > > >> https://github.com/apache/kafka/pull/5582/)
>> > > > >> > > that implements server-side kill of expired OAUTHBEARER
>> > > connections.
>> > > > >> No
>> > > > >> > > tests yet since we still haven't settled on a final approach
>> > > > >> (low-level
>> > > > >> > vs.
>> > > > >> > > high-level).
>> > > > >> > >
>> > > > >> > > I also updated the KIP to reflect the latest discussion and
>> PR
>> > as
>> > > > >> > follows:
>> > > > >> > >
>> > > > >> > >    - Include support for brokers killing connections as part
>> of
>> > > this
>> > > > >> KIP
>> > > > >> > >    (rather than deferring it to a future KIP as was
>> originally
>> > > > >> > mentioned; the
>> > > > >> > >    PR now includes it as mentioned -- it was very easy to
>> add)
>> > > > >> > >    - Added metrics (they will mirror existing ones related to
>> > > > >> > >    authentications; I have not added those to the PR)
>> > > > >> > >    - Updated the implementation description to reflect the
>> > current
>> > > > >> state
>> > > > >> > >    of the PR, which is a high-level, one-size-fits-all
>> approach
>> > > (as
>> > > > >> > opposed to
>> > > > >> > >    my initial, even-higher-level approach)
>> > > > >> > >    - Added a "Rejected Alternative" for the first version of
>> the
>> > > PR,
>> > > > >> > >    which injected requests directly into synchronous I/O
>> > clients'
>> > > > >> queues
>> > > > >> > >    - Added a "Rejected Alternative" for the low-level
>> approach
>> > as
>> > > > >> > >    suggested, but of course we have not formally decided to
>> > reject
>> > > > >> this
>> > > > >> > >    approach or adopt the current PR implementation.
>> > > > >> > >
>> > > > >> > > I'll think about where we stand some more before responding
>> > again.
>> > > > >> > Thanks
>> > > > >> > > for the above reply.
>> > > > >> > >
>> > > > >> > > Ron
>> > > > >> > >
>> > > > >> > > On Wed, Sep 12, 2018 at 1:36 PM Rajini Sivaram <
>> > > > >> rajinisiva...@gmail.com>
>> > > > >> > > wrote:
>> > > > >> > >
>> > > > >> > >> Hi Ron,
>> > > > >> > >>
>> > > > >> > >> Thank you for summarising, I think it covers the differences
>> > > > between
>> > > > >> the
>> > > > >> > >> two approaches well.
>> > > > >> > >>
>> > > > >> > >> A few minor points to answer the questions in there:
>> > > > >> > >>
>> > > > >> > >> 1) When re-authetication is initiated in the Selector during
>> > > > poll(),
>> > > > >> we
>> > > > >> > >> can
>> > > > >> > >> move an idle channel to re-authentication state. It is
>> similar
>> > to
>> > > > >> > >> injecting
>> > > > >> > >> requests, but achieved by changing channel back to
>> > authenticating
>> > > > >> state.
>> > > > >> > >>
>> > > > >> > >> 3) To clarify why I think re-authentication should fit in
>> with
>> > > our
>> > > > >> > >> authentication design: My point was not about a specific
>> > > connection
>> > > > >> > being
>> > > > >> > >> usable or not usable. It was about what happens at the
>> client
>> > API
>> > > > >> level.
>> > > > >> > >> Our client API (producer/consumer/admin client etc.)
>> currently
>> > > > assume
>> > > > >> > that
>> > > > >> > >> a single broker authentication failure is a fatal error
>> that is
>> > > > never
>> > > > >> > >> retried because we assume that broker only ever fails an
>> > > > >> authentication
>> > > > >> > >> request if credentials are invalid. If we ever decide to
>> > support
>> > > > >> cases
>> > > > >> > >> where broker occasionally fails an authentication request
>> due
>> > to
>> > > a
>> > > > >> > >> transient failure, we need to do more around how we handle
>> > > > >> > authentication
>> > > > >> > >> failures in clients. We may decide that it is ok to close
>> the
>> > > > >> connection
>> > > > >> > >> for authentication and not for re-authentication as you
>> > > mentioned,
>> > > > >> but
>> > > > >> > we
>> > > > >> > >> need to change the way this disconnection is handled by
>> > clients.
>> > > So
>> > > > >> IMO,
>> > > > >> > >> we
>> > > > >> > >> should either add support for transient retriable
>> > authentication
>> > > > >> > failures
>> > > > >> > >> properly or not retry for any scenario. Personally, I don't
>> > think
>> > > > we
>> > > > >> > would
>> > > > >> > >> want to retry all authentication failures even if it is a
>> > > > >> > >> re-authentication, I think we could (at some point in
>> future),
>> > > > allow
>> > > > >> > >> brokers to return an error code that indicates that it is a
>> > > > transient
>> > > > >> > >> broker-side failure rather than invalid credentials and
>> handle
>> > > the
>> > > > >> error
>> > > > >> > >> differently. I see no reason at that point why we wouldn't
>> > handle
>> > > > >> > >> authentication and re-authentication in the same way.
>> > > > >> > >>
>> > > > >> > >> 4) As you said, the high-level approach would be bigger than
>> > the
>> > > > >> > low-level
>> > > > >> > >> approach in terms of LOC. But I wouldn't be too concerned
>> about
>> > > > >> lines of
>> > > > >> > >> code. My bigger concern was about modularity. Our security
>> code
>> > > is
>> > > > >> > already
>> > > > >> > >> complex, protocols like Kerberos and SSL that we use from
>> the
>> > JRE
>> > > > >> make
>> > > > >> > >> problem diagnosis hard. Async I/O makes the networking code
>> > > > complex.
>> > > > >> You
>> > > > >> > >> need to understand networking layer to work with the
>> security
>> > > > layer,
>> > > > >> but
>> > > > >> > >> the rest of the code base doesn't rely on knowledge of
>> > > > >> network/security
>> > > > >> > >> layers. My main concern about the high-level approach is
>> that
>> > it
>> > > > >> spans
>> > > > >> > >> these boundaries, making it harder to maintain in the long
>> run.
>> > > > >> > >>
>> > > > >> > >>
>> > > > >> > >> On Wed, Sep 12, 2018 at 10:23 AM, Stanislav Kozlovski <
>> > > > >> > >> stanis...@confluent.io> wrote:
>> > > > >> > >>
>> > > > >> > >> > Hi Ron, Rajini
>> > > > >> > >> >
>> > > > >> > >> > Thanks for summarizing the discussion so far, Ron!
>> > > > >> > >> >
>> > > > >> > >> > 1) How often do we have such long-lived connection
>> idleness
>> > > (e.g
>> > > > >> 5-10
>> > > > >> > >> > minutes) in practice?
>> > > > >> > >> >
>> > > > >> > >> > 3) I agree that retries for re-authentication are useful.
>> > > > >> > >> >
>> > > > >> > >> > 4) The interleaving of requests sounds like a great
>> feature
>> > to
>> > > > >> have,
>> > > > >> > but
>> > > > >> > >> > the tradeoff against code complexity is a tough one. I
>> would
>> > > > >> > personally
>> > > > >> > >> go
>> > > > >> > >> > with the simpler approach since you could always add
>> > > interleaving
>> > > > >> on
>> > > > >> > >> top if
>> > > > >> > >> > the community decides the latency should be better.
>> > > > >> > >> >
>> > > > >> > >> > Best,
>> > > > >> > >> > Stanislav
>> > > > >> > >> >
>> > > > >> > >> > On Tue, Sep 11, 2018 at 5:00 AM Ron Dagostino <
>> > > rndg...@gmail.com
>> > > > >
>> > > > >> > >> wrote:
>> > > > >> > >> >
>> > > > >> > >> > > Hi everyone.  I've updated the PR to reflect the latest
>> > > > >> conclusions
>> > > > >> > >> from
>> > > > >> > >> > > this ongoing discussion.  The KIP still needs the
>> suggested
>> > > > >> > updates; I
>> > > > >> > >> > will
>> > > > >> > >> > > do that later this week.  II agree with Rajini that some
>> > > > >> additional
>> > > > >> > >> > > feedback from the community at large would be very
>> helpful
>> > at
>> > > > >> this
>> > > > >> > >> point
>> > > > >> > >> > in
>> > > > >> > >> > > time.
>> > > > >> > >> > >
>> > > > >> > >> > > Here's where we stand.
>> > > > >> > >> > >
>> > > > >> > >> > > We have 2 separate implementations for re-authenticating
>> > > > existing
>> > > > >> > >> > > connections -- a so-called "low-level" approach and a
>> > > > (relatively
>> > > > >> > >> > speaking)
>> > > > >> > >> > > "high-level" approach -- and we agree on how they
>> should be
>> > > > >> > compared.
>> > > > >> > >> > > Specifically, Rajini has provided a mechanism that works
>> > at a
>> > > > >> > >> relatively
>> > > > >> > >> > > low level in the stack by intercepting network sends and
>> > > > queueing
>> > > > >> > >> them up
>> > > > >> > >> > > while re-authentication happens; then the queued sends
>> are
>> > > sent
>> > > > >> > after
>> > > > >> > >> > > re-authentication succeeds, or the connection is closed
>> if
>> > > > >> > >> > > re-authentication fails.  See the prototype commit at
>> > > > >> > >> > >
>> > > > >> > >> > > https://github.com/rajinisivaram/kafka/commit/
>> > b9d711907ad843
>> > > > >> > >> > c11d17e80d6743bfb1d4e3f3fd
>> > > > >> > >> > > .
>> > > > >> > >> > >
>> > > > >> > >> > > I have an implementation that works higher up in the
>> stack;
>> > > it
>> > > > >> > injects
>> > > > >> > >> > > authentication requests into the KafkaClient via a new
>> > method
>> > > > >> added
>> > > > >> > to
>> > > > >> > >> > that
>> > > > >> > >> > > interface, and the implementation (i.e. NetworkClient)
>> > sends
>> > > > them
>> > > > >> > when
>> > > > >> > >> > > poll() is called.  The updated PR is available at
>> > > > >> > >> > > https://github.com/apache/kafka/pull/5582/.
>> > > > >> > >> > >
>> > > > >> > >> > > Here is how we think these two approaches should be
>> > compared.
>> > > > >> > >> > >
>> > > > >> > >> > > 1) *When re-authentication starts*.  The low-level
>> approach
>> > > > >> > initiates
>> > > > >> > >> > > re-authentication only if/when the connection is
>> actually
>> > > used,
>> > > > >> so
>> > > > >> > it
>> > > > >> > >> may
>> > > > >> > >> > > start after the existing credential expires; the
>> current PR
>> > > > >> > >> > implementation
>> > > > >> > >> > > injects re-authentication requests into the existing
>> flow,
>> > > and
>> > > > >> > >> > > re-authentication starts immediately regardless of
>> whether
>> > or
>> > > > not
>> > > > >> > the
>> > > > >> > >> > > connection is being used for something else.  Rajini
>> > believes
>> > > > the
>> > > > >> > >> > low-level
>> > > > >> > >> > > approach can be adjusted to re-authenticate idle
>> > connections
>> > > > >> > (Rajini,
>> > > > >> > >> I
>> > > > >> > >> > > don't see how this can be done without injecting
>> requests,
>> > > > which
>> > > > >> is
>> > > > >> > >> what
>> > > > >> > >> > > the high-level connection is doing, but I am probably
>> > missing
>> > > > >> > >> something
>> > > > >> > >> > --
>> > > > >> > >> > > no need to go into it unless it is easy to explain.)
>> > > > >> > >> > >
>> > > > >> > >> > > 2) *When requests not related to re-authentication are
>> able
>> > > to
>> > > > >> use
>> > > > >> > the
>> > > > >> > >> > > re-authenticating connection*.  The low-level approach
>> > > finishes
>> > > > >> > >> > > re-authentication completely before allowing anything
>> else
>> > to
>> > > > >> > traverse
>> > > > >> > >> > the
>> > > > >> > >> > > connection, and we agree that this is how the low-level
>> > > > >> > implementation
>> > > > >> > >> > must
>> > > > >> > >> > > work without significant work/changes.  The current PR
>> > > > >> > implementation
>> > > > >> > >> > > interleaves re-authentication requests with the existing
>> > flow
>> > > > in
>> > > > >> the
>> > > > >> > >> > > asynchronous I/O uses cases (Consumer, Producer, Admin
>> > > Client,
>> > > > >> > etc.),
>> > > > >> > >> and
>> > > > >> > >> > > it allows the two synchronous use cases
>> > > > (ControllerChannelManager
>> > > > >> > and
>> > > > >> > >> > > ReplicaFetcherBlockingSend/ReplicaFetcherThread) to
>> decide
>> > > > which
>> > > > >> > style
>> > > > >> > >> > they
>> > > > >> > >> > > want.  I (somewhat arbitrarily, to prove out the
>> > flexibility
>> > > of
>> > > > >> the
>> > > > >> > >> > > high-level approach) coded ControllerChannelManager to
>> do
>> > > > >> complete,
>> > > > >> > >> > > non-interleaved re-authentication and
>> > > > ReplicaFetcherBlockingSend/
>> > > > >> > >> > > ReplicaFetcherThread to interleave requests.  The
>> approach
>> > > has
>> > > > >> > >> impacts on
>> > > > >> > >> > > the maximum size of latency spikes: interleaving
>> requests
>> > can
>> > > > >> > decrease
>> > > > >> > >> > the
>> > > > >> > >> > > latency.  The benefit of interleaving is tough to
>> evaluate
>> > > > >> because
>> > > > >> > it
>> > > > >> > >> > isn't
>> > > > >> > >> > > clear what the latency requirement really is.  Note that
>> > > > >> > >> > re-authentication
>> > > > >> > >> > > can entail several network round-trips between the
>> client
>> > and
>> > > > the
>> > > > >> > >> broker.
>> > > > >> > >> > > Comments in this area would be especially appreciated.
>> > > > >> > >> > >
>> > > > >> > >> > > 3) *What happens if re-authentication fails (i.e. retry
>> > > > >> > >> capability)*.  I
>> > > > >> > >> > > think this is where we have not yet settled on what the
>> > > > >> requirement
>> > > > >> > is
>> > > > >> > >> > > (even more so than the issue of potential latency
>> > mitigation
>> > > > >> > >> > > requirements).  Rajini, you had mentioned that
>> > > > re-authentication
>> > > > >> > >> should
>> > > > >> > >> > > work the same way as authentication, but I see the two
>> > > > >> situations as
>> > > > >> > >> > being
>> > > > >> > >> > > asymmetric.  In the authentication case, if
>> authentication
>> > > > fails,
>> > > > >> > the
>> > > > >> > >> > > connection was never fully established and could not be
>> > used,
>> > > > >> and it
>> > > > >> > >> is
>> > > > >> > >> > > closed -- TLS negotiation may have taken place, so that
>> > > effort
>> > > > is
>> > > > >> > >> lost,
>> > > > >> > >> > but
>> > > > >> > >> > > beyond that nothing else is lost.  In the
>> re-authentication
>> > > > case
>> > > > >> the
>> > > > >> > >> > > connection is fully established, it is in use, and in
>> fact
>> > it
>> > > > can
>> > > > >> > >> remain
>> > > > >> > >> > in
>> > > > >> > >> > > use for some time going forward as long as the existing
>> > > > >> credential
>> > > > >> > >> > remains
>> > > > >> > >> > > unexpired; abandoning it at this point due to a
>> > > > re-authentication
>> > > > >> > >> failure
>> > > > >> > >> > > (which can occur due to no fault of the client -- i.e. a
>> > > remote
>> > > > >> > >> directory
>> > > > >> > >> > > or OAuth server being temporarily down) abandons a fully
>> > > > >> functioning
>> > > > >> > >> > > connection with remaining lifetime.  Am I thinking about
>> > this
>> > > > >> > >> reasonably?
>> > > > >> > >> > > I still tend to believe that retries of failed
>> > > > re-authentications
>> > > > >> > are
>> > > > >> > >> a
>> > > > >> > >> > > requirement.
>> > > > >> > >> > >
>> > > > >> > >> > > 4) *Size*. The low-level approach is smaller in terms of
>> > > code.
>> > > > >> It
>> > > > >> > is
>> > > > >> > >> a
>> > > > >> > >> > > prototype, so it doesn't have everything the high-level
>> > > > approach
>> > > > >> > has,
>> > > > >> > >> > but I
>> > > > >> > >> > > have split the PR for the high-level approach into two
>> > > separate
>> > > > >> > >> commits
>> > > > >> > >> > to
>> > > > >> > >> > > facilitate a more apples-to-apples comparison: the first
>> > > commit
>> > > > >> > >> contains
>> > > > >> > >> > > infrastructure that would have to be added to the
>> low-level
>> > > > >> > prototype
>> > > > >> > >> if
>> > > > >> > >> > we
>> > > > >> > >> > > went with that, and the second commit has everything
>> > specific
>> > > > to
>> > > > >> the
>> > > > >> > >> > > high-level approach.  So comparing the low-level
>> prototype
>> > > > commit
>> > > > >> > >> (~350
>> > > > >> > >> > > changes) to the second commit in the high-level PR
>> (~1400
>> > > > >> changes)
>> > > > >> > is
>> > > > >> > >> > > reasonable. The high-level approach at this point is
>> about
>> > 4
>> > > > >> times
>> > > > >> > as
>> > > > >> > >> > big,
>> > > > >> > >> > > though it does have lots of error/sanity checking and
>> > > > >> functionality
>> > > > >> > >> (such
>> > > > >> > >> > > as retry) that would to at least some degree have to be
>> > added
>> > > > to
>> > > > >> the
>> > > > >> > >> > > low-level implementation.  Still, the high-level
>> approach
>> > is
>> > > > (and
>> > > > >> > will
>> > > > >> > >> > > likely remain) somewhat bigger than the low-level
>> approach.
>> > > > >> > >> > >
>> > > > >> > >> > > I hope I presented this in a balanced and accurate way;
>> > > Rajini,
>> > > > >> > please
>> > > > >> > >> > > correct me if I got anything wrong or left out anything
>> > > > >> important.
>> > > > >> > >> > > Apologies in advance if that is the case -- it is
>> > unintended.
>> > > > >> > >> > >
>> > > > >> > >> > > Again, comments/discussion from the wider community at
>> this
>> > > > >> juncture
>> > > > >> > >> > would
>> > > > >> > >> > > be especially appreciated.
>> > > > >> > >> > >
>> > > > >> > >> > > Ron
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > >
>> > > > >> > >> > > On Mon, Sep 10, 2018 at 7:42 AM Rajini Sivaram <
>> > > > >> > >> rajinisiva...@gmail.com>
>> > > > >> > >> > > wrote:
>> > > > >> > >> > >
>> > > > >> > >> > > > Hi Ron,
>> > > > >> > >> > > >
>> > > > >> > >> > > > Thank you for the analysis. Yes, I agree with the
>> > > differences
>> > > > >> you
>> > > > >> > >> have
>> > > > >> > >> > > > pointed out between the two approaches.
>> > > > >> > >> > > >
>> > > > >> > >> > > >    1. Re-authenticating idle connections (or
>> connections
>> > > > >> nearing
>> > > > >> > >> idle
>> > > > >> > >> > > >    timeout): With the lower-level approach, there is
>> > > nothing
>> > > > >> > >> stopping
>> > > > >> > >> > us
>> > > > >> > >> > > > from
>> > > > >> > >> > > >    re-authenticating idle connections. We could either
>> > > > consider
>> > > > >> > idle
>> > > > >> > >> > > >    connections for re-authentication or we could
>> > implement
>> > > > >> code in
>> > > > >> > >> > broker
>> > > > >> > >> > > > to
>> > > > >> > >> > > >    kill connections that deals with delays introduced
>> by
>> > > > >> idleness.
>> > > > >> > >> > Since
>> > > > >> > >> > > we
>> > > > >> > >> > > >    expect token lifetimes to be much higher than
>> > connection
>> > > > >> expiry
>> > > > >> > >> > time,
>> > > > >> > >> > > >    either would work. And the second approach is
>> probably
>> > > > >> better.
>> > > > >> > >> > > >    2. Interleaving authentication requests and
>> > application
>> > > > >> > requests
>> > > > >> > >> to
>> > > > >> > >> > > >    reduce impact on latency: It is not impossible to
>> > > > interleave
>> > > > >> > with
>> > > > >> > >> > the
>> > > > >> > >> > > >    low-level approach, but it adds complexity and
>> reduces
>> > > the
>> > > > >> > value
>> > > > >> > >> of
>> > > > >> > >> > > this
>> > > > >> > >> > > >    approach. So it will be good to understand the
>> > > > requirements
>> > > > >> in
>> > > > >> > >> terms
>> > > > >> > >> > > of
>> > > > >> > >> > > >    latency. In terms of comparing the two approaches,
>> it
>> > is
>> > > > >> fair
>> > > > >> > to
>> > > > >> > >> > > compare
>> > > > >> > >> > > >    non-interleaved low-level with the naturally
>> > interleaved
>> > > > >> > >> high-level
>> > > > >> > >> > > >    approach.
>> > > > >> > >> > > >    3. Retries: I don't think requirement for retries
>> is
>> > > > >> different
>> > > > >> > >> > between
>> > > > >> > >> > > >    authentication and re-authentication from a
>> client's
>> > > point
>> > > > >> of
>> > > > >> > >> view.
>> > > > >> > >> > We
>> > > > >> > >> > > >    should either support retries for both or not at
>> all.
>> > We
>> > > > >> > >> currently
>> > > > >> > >> > > > process
>> > > > >> > >> > > >    authentication failures as fatal errors. We expect
>> > that
>> > > if
>> > > > >> you
>> > > > >> > >> are
>> > > > >> > >> > > using
>> > > > >> > >> > > >    external authentication servers, those servers
>> will be
>> > > > >> highly
>> > > > >> > >> > > available.
>> > > > >> > >> > > >    Our built-in authentication mechanisms avoid
>> accessing
>> > > > >> external
>> > > > >> > >> > > servers
>> > > > >> > >> > > > in
>> > > > >> > >> > > >    the authentication path (during authentication,
>> > > > >> verification is
>> > > > >> > >> > > > performed
>> > > > >> > >> > > >    using private/public keys or cache lookup). This is
>> > > > >> necessary
>> > > > >> > in
>> > > > >> > >> our
>> > > > >> > >> > > > design
>> > > > >> > >> > > >    since authentications are performed synchronously
>> on
>> > the
>> > > > >> > network
>> > > > >> > >> > > thread.
>> > > > >> > >> > > >
>> > > > >> > >> > > > One more point with the lower-level mechanism: If one
>> day
>> > > we
>> > > > >> > decided
>> > > > >> > >> > that
>> > > > >> > >> > > > we want to extend this for SSL, it would be possible
>> to
>> > > > change
>> > > > >> > just
>> > > > >> > >> the
>> > > > >> > >> > > > transport layer and make it work for SSL. We may never
>> > want
>> > > > to
>> > > > >> do
>> > > > >> > >> this,
>> > > > >> > >> > > but
>> > > > >> > >> > > > thought I would point out anyway.
>> > > > >> > >> > > >
>> > > > >> > >> > > > I think the next step would be to add the low-level
>> > > approach
>> > > > to
>> > > > >> > the
>> > > > >> > >> KIP
>> > > > >> > >> > > > under `Rejected Alternatives` with details on the
>> > > > differences.
>> > > > >> And
>> > > > >> > >> more
>> > > > >> > >> > > > detail on requirements covering latency and retries in
>> > the
>> > > > >> body of
>> > > > >> > >> the
>> > > > >> > >> > > > KIP.  For "Rejected Alternatives", can we add
>> > sub-sections
>> > > (I
>> > > > >> > think
>> > > > >> > >> > there
>> > > > >> > >> > > > are two approaches there now, but you need to read
>> > through
>> > > to
>> > > > >> > figure
>> > > > >> > >> > that
>> > > > >> > >> > > > out, so sub-titles would help).
>> > > > >> > >> > > >
>> > > > >> > >> > > > Once the KIP is updated, it will be good to get more
>> > > feedback
>> > > > >> from
>> > > > >> > >> the
>> > > > >> > >> > > > community to decide on the approach to adopt.
>> > > > >> > >> > > >
>> > > > >> > >> > > >
>> > > > >> > >> > > > On Sat, Sep 8, 2018 at 1:27 PM, Ron Dagostino <
>> > > > >> rndg...@gmail.com>
>> > > > >> > >> > wrote:
>> > > > >> > >> > > >
>> > > > >> > >> > > > > Hi yet again, Rajini.  If we decide that
>> interleaving
>> > is
>> > > > >> > >> impossible
>> > > > >> > >> > > with
>> > > > >> > >> > > > > the low-level approach but we still want to at least
>> > > > support
>> > > > >> the
>> > > > >> > >> > > > > possibility given that it reduces the size of
>> latency
>> > > > spikes,
>> > > > >> > >> then I
>> > > > >> > >> > do
>> > > > >> > >> > > > > have a suggestion.  I documented in the KIP how I
>> > > rejected
>> > > > a
>> > > > >> > >> single,
>> > > > >> > >> > > > > one-size-fits-all queue approach because we don't
>> know
>> > > when
>> > > > >> > poll()
>> > > > >> > >> > will
>> > > > >> > >> > > > be
>> > > > >> > >> > > > > called in the synchronous I/O use case.  An
>> advantage
>> > of
>> > > > >> such an
>> > > > >> > >> > > approach
>> > > > >> > >> > > > > -- if it would have worked, which it didn't -- is
>> that
>> > it
>> > > > >> would
>> > > > >> > >> have
>> > > > >> > >> > > been
>> > > > >> > >> > > > > transparent to the owner of the NetworkClient
>> instance
>> > > > (this
>> > > > >> is
>> > > > >> > >> one
>> > > > >> > >> > of
>> > > > >> > >> > > > the
>> > > > >> > >> > > > > big advantages of the low-level approach, after
>> all).
>> > > But
>> > > > we
>> > > > >> > >> could
>> > > > >> > >> > > make
>> > > > >> > >> > > > > the one-size-fits-all queue approach work if we are
>> > > willing
>> > > > >> to
>> > > > >> > >> impose
>> > > > >> > >> > > > some
>> > > > >> > >> > > > > requirements on synchronous I/O users of
>> NetworkClient.
>> > > > >> > >> > Specifically,
>> > > > >> > >> > > we
>> > > > >> > >> > > > > could add a method to the
>> > > > >> org.apache.kafka.clients.KafkaClient
>> > > > >> > >> > > interface
>> > > > >> > >> > > > > (which NetworkClient implements) as follows:
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >     /**
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * Return true if any node has re-authentication
>> > > > requests
>> > > > >> > >> waiting
>> > > > >> > >> > > to
>> > > > >> > >> > > > be
>> > > > >> > >> > > > > sent. A
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * call to {@link #poll(long, long)} is
>> required to
>> > > > send
>> > > > >> > such
>> > > > >> > >> > > > requests.
>> > > > >> > >> > > > > An owner
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * of this instance that does not implement a
>> run
>> > > loop
>> > > > to
>> > > > >> > >> > > repeatedly
>> > > > >> > >> > > > > call
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * {@link #poll(long, long)} but instead only
>> sends
>> > > > >> requests
>> > > > >> > >> > > > > synchronously
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * on-demand must call this method periodically
>> --
>> > > and
>> > > > >> > invoke
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * {@link #poll(long, long)} if the return
>> value is
>> > > > >> {@code
>> > > > >> > >> true}
>> > > > >> > >> > --
>> > > > >> > >> > > > to
>> > > > >> > >> > > > > ensure
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * that any re-authentication requests that have
>> > ben
>> > > > >> > injected
>> > > > >> > >> are
>> > > > >> > >> > > > sent
>> > > > >> > >> > > > > in a
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * timely fashion.
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      *
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      * @return true if any node has
>> re-authentication
>> > > > >> requests
>> > > > >> > >> > waiting
>> > > > >> > >> > > to
>> > > > >> > >> > > > > be sent
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >      */
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >     default boolean hasReauthenticationRequests() {
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >         return false;
>> > > > >> > >> > > > >
>> > > > >> > >> > > > >     }
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > If we are willing to add an additional method like
>> this
>> > > and
>> > > > >> make
>> > > > >> > >> the
>> > > > >> > >> > > > minor
>> > > > >> > >> > > > > adjustments to the code associated with the few
>> > > synchronous
>> > > > >> use
>> > > > >> > >> cases
>> > > > >> > >> > > > then
>> > > > >> > >> > > > > I think the high-level approach will work.  We would
>> > then
>> > > > >> have
>> > > > >> > the
>> > > > >> > >> > > > > possibility of further parameterizing the various
>> > > > synchronous
>> > > > >> > I/O
>> > > > >> > >> use
>> > > > >> > >> > > > > cases.  For example, there are currently 3:
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > ControllerChannelManager
>> > > > >> > >> > > > > KafkaProducer, via Sender
>> > > > >> > >> > > > > ReplicaFetcherBlockingSend, via ReplicaFetcherThread
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > Is it conceivable that one of these use cases might
>> be
>> > > more
>> > > > >> > >> > > > > latency-sensitive than others and might desire
>> > > > >> interleaving?  A
>> > > > >> > >> > > > high-level
>> > > > >> > >> > > > > approach would give us the option of configuring
>> each
>> > use
>> > > > >> case
>> > > > >> > >> > > > accordingly.
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > Ron
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > On Fri, Sep 7, 2018 at 10:50 PM Ron Dagostino <
>> > > > >> > rndg...@gmail.com>
>> > > > >> > >> > > wrote:
>> > > > >> > >> > > > >
>> > > > >> > >> > > > > > Hi again, Rajini.  It occurs to me that from a
>> > > *behavior*
>> > > > >> > >> > perspective
>> > > > >> > >> > > > > > there are really 3 fundamental differences between
>> > the
>> > > > >> > low-level
>> > > > >> > >> > > > approach
>> > > > >> > >> > > > > > you provided and the high-level approach as it
>> > > currently
>> > > > >> > exists
>> > > > >> > >> in
>> > > > >> > >> > > the
>> > > > >> > >> > > > > PR:
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 1) *When re-authentication starts*.  The low-level
>> > > > approach
>> > > > >> > >> > initiates
>> > > > >> > >> > > > > > re-authentication only if/when the connection is
>> > > actually
>> > > > >> > used,
>> > > > >> > >> so
>> > > > >> > >> > it
>> > > > >> > >> > > > may
>> > > > >> > >> > > > > > start after the existing credential expires; the
>> > > current
>> > > > PR
>> > > > >> > >> > > > > implementation
>> > > > >> > >> > > > > > injects re-authentication requests into the
>> existing
>> > > > flow,
>> > > > >> and
>> > > > >> > >> > > > > > re-authentication starts immediately regardless of
>> > > > whether
>> > > > >> or
>> > > > >> > >> not
>> > > > >> > >> > the
>> > > > >> > >> > > > > > connection is being used for something else.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 2) *When requests not related to re-authentication
>> > can
>> > > > use
>> > > > >> the
>> > > > >> > >> > > > > > re-authenticating connection*.  The low-level
>> > approach
>> > > > >> > finishes
>> > > > >> > >> > > > > > re-authentication completely before allowing
>> anything
>> > > > else
>> > > > >> to
>> > > > >> > >> > travers
>> > > > >> > >> > > > the
>> > > > >> > >> > > > > > connection; the current PR implementation
>> interleaves
>> > > > >> > >> > > re-authentication
>> > > > >> > >> > > > > > requests with existing flow requests.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 3) *What happens if re-authentication fails*.  The
>> > > > >> low-level
>> > > > >> > >> > approach
>> > > > >> > >> > > > > > results in a closed connection and does not
>> support
>> > > > >> retries --
>> > > > >> > >> at
>> > > > >> > >> > > least
>> > > > >> > >> > > > > as
>> > > > >> > >> > > > > > currently implemented; the current PR
>> implementation
>> > > > >> supports
>> > > > >> > >> > > retries.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > Do you agree that these are the (only?) behavioral
>> > > > >> > differences?
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > For these facets of behavior, I wonder what the
>> > > > >> requirements
>> > > > >> > are
>> > > > >> > >> > for
>> > > > >> > >> > > > this
>> > > > >> > >> > > > > > feature.  I think they are as follows:
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 1) *When re-authentication starts*: I don't think
>> we
>> > > > have a
>> > > > >> > hard
>> > > > >> > >> > > > > > requirement here when considered in isolation --
>> > > whether
>> > > > >> > >> > > > > re-authentication
>> > > > >> > >> > > > > > starts immediately or is delayed until the
>> connection
>> > > is
>> > > > >> used
>> > > > >> > >> > > probably
>> > > > >> > >> > > > > > doesn't matter.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 2) *When requests not related to re-authentication
>> > can
>> > > > use
>> > > > >> the
>> > > > >> > >> > > > > > re-authenticating connection*: there is a tradeoff
>> > here
>> > > > >> > between
>> > > > >> > >> > > latency
>> > > > >> > >> > > > > > and ability to debug re-authentication problems.
>> > > > Delaying
>> > > > >> use
>> > > > >> > >> of
>> > > > >> > >> > the
>> > > > >> > >> > > > > > connection until re-authentication finishes
>> results
>> > in
>> > > > >> bigger
>> > > > >> > >> > latency
>> > > > >> > >> > > > > > spikes but keeps re-authentication requests
>> somewhat
>> > > > >> together;
>> > > > >> > >> > > > > interleaving
>> > > > >> > >> > > > > > minimizes the size of individual latency spikes
>> but
>> > > adds
>> > > > >> some
>> > > > >> > >> > > > separation
>> > > > >> > >> > > > > > between the requests.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 3) *What happens if re-authentication fails*: I
>> > believe
>> > > > we
>> > > > >> > have
>> > > > >> > >> a
>> > > > >> > >> > > clear
>> > > > >> > >> > > > > > requirement for retry capability given what I have
>> > > > written
>> > > > >> > >> > > previously.
>> > > > >> > >> > > > > Do
>> > > > >> > >> > > > > > you agree?  Note that while the current low-level
>> > > > >> > implementation
>> > > > >> > >> > does
>> > > > >> > >> > > > not
>> > > > >> > >> > > > > > support retry, I have been thinking about how that
>> > can
>> > > be
>> > > > >> > done,
>> > > > >> > >> > and I
>> > > > >> > >> > > > am
>> > > > >> > >> > > > > > pretty sure it can be.  We can keep the old
>> > > > authenticators
>> > > > >> on
>> > > > >> > >> the
>> > > > >> > >> > > > client
>> > > > >> > >> > > > > > and server sides and put them back into place if
>> the
>> > > > >> > >> > > re-authentication
>> > > > >> > >> > > > > > fails; we would also have to make sure the server
>> > side
>> > > > >> doesn't
>> > > > >> > >> > delay
>> > > > >> > >> > > > any
>> > > > >> > >> > > > > > failed re-authentication result and also doesn't
>> > close
>> > > > the
>> > > > >> > >> > connection
>> > > > >> > >> > > > > upon
>> > > > >> > >> > > > > > re-authentication failure.  I think I see how to
>> do
>> > all
>> > > > of
>> > > > >> > that.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > There are some interactions between the above
>> > > > requirements.
>> > > > >> > If
>> > > > >> > >> > > > > > re-authentication can't start immediately and has
>> to
>> > > wait
>> > > > >> for
>> > > > >> > >> the
>> > > > >> > >> > > > > > connection to be used then that precludes
>> > interleaving
>> > > > >> because
>> > > > >> > >> we
>> > > > >> > >> > > can't
>> > > > >> > >> > > > > be
>> > > > >> > >> > > > > > sure that the credential will be active by the
>> time
>> > it
>> > > is
>> > > > >> used
>> > > > >> > >> --
>> > > > >> > >> > if
>> > > > >> > >> > > it
>> > > > >> > >> > > > > > isn't active, and we allow interleaving, then
>> > requests
>> > > > not
>> > > > >> > >> related
>> > > > >> > >> > to
>> > > > >> > >> > > > > > re-authentication will fail if server-side
>> > > > >> > >> > > > > > connection-close-due-to-expired-credential
>> > > > functionality is
>> > > > >> > in
>> > > > >> > >> > place.
>> > > > >> > >> > > > > Also
>> > > > >> > >> > > > > > note that any such server-side
>> > connection-close-due-to-
>> > > > >> > >> > > > > expired-credential
>> > > > >> > >> > > > > > functionality would likely have to avoid closing a
>> > > > >> connection
>> > > > >> > >> until
>> > > > >> > >> > > it
>> > > > >> > >> > > > is
>> > > > >> > >> > > > > > used for anything other than re-authentication --
>> it
>> > > must
>> > > > >> > allow
>> > > > >> > >> > > > > > re-authentication requests through when the
>> > credential
>> > > is
>> > > > >> > >> expired.
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > Given all of the above, it feels to me like the
>> > > low-level
>> > > > >> > >> solution
>> > > > >> > >> > is
>> > > > >> > >> > > > > > viable only under the following conditions:
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > 1) We must accept a delay in when
>> re-authentication
>> > > > occurs
>> > > > >> to
>> > > > >> > >> when
>> > > > >> > >> > > the
>> > > > >> > >> > > > > > connection is used
>> > > > >> > >> > > > > > 2) We must accept the bigger latency spikes
>> > associated
>> > > > with
>> > > > >> > not
>> > > > >> > >> > > > > > interleaving requests
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > Does this sound right to you, and if so, do you
>> find
>> > > > these
>> > > > >> > >> > conditions
>> > > > >> > >> > > > > > acceptable?  Or have I missed something and/or
>> made
>> > > > >> incorrect
>> > > > >> > >> > > > assumptions
>> > > > >> > >> > > > > > somewhere?
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > Ron
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > > On Fri, Sep 7, 2018 at 5:19 PM Ron Dagostino <
>> > > > >> > rndg...@gmail.com
>> > > > >> > >> >
>> > > > >> > >> > > > wrote:
>> > > > >> > >> > > > > >
>> > > > >> > >> > > > > >> Hi Rajini.  The code really helped me to
>> understand
>> > > what
>> > > > >> you
>> > > > >> > >> were
>> > > > >> > >> > > > > >> thinking -- thanks.  I'm still digesting, but
>> here
>> > are
>> > > > >> some
>> > > > >> > >> quick
>> > > > >> > >> > > > > >> observations:
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> Your approach (I'll call it the "low-level"
>> > approach,
>> > > as
>> > > > >> > >> compared
>> > > > >> > >> > to
>> > > > >> > >> > > > the
>> > > > >> > >> > > > > >> existing PR, which works at a higher level of
>> > > > >> abstraction) --
>> > > > >> > >> the
>> > > > >> > >> > > > > low-level
>> > > > >> > >> > > > > >> approach is certainly intriguing.  The smaller
>> code
>> > > size
>> > > > >> is
>> > > > >> > >> > welcome,
>> > > > >> > >> > > > of
>> > > > >> > >> > > > > >> course, as is the fact that re-authentication
>> simply
>> > > > works
>> > > > >> > for
>> > > > >> > >> > > > everyone
>> > > > >> > >> > > > > >> regardless of the style of use (async vs. sync
>> I/O).
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> I did notice that re-authentication of the
>> > connection
>> > > > >> starts
>> > > > >> > >> only
>> > > > >> > >> > > > > if/when
>> > > > >> > >> > > > > >> the client uses the connection.  For example, if
>> I
>> > > run a
>> > > > >> > >> console
>> > > > >> > >> > > > > producer,
>> > > > >> > >> > > > > >> re-authentication does not happen unless I try to
>> > > > produce
>> > > > >> > >> > something.
>> > > > >> > >> > > > On
>> > > > >> > >> > > > > >> the one hand this is potentially good -- if the
>> > client
>> > > > >> isn't
>> > > > >> > >> using
>> > > > >> > >> > > the
>> > > > >> > >> > > > > >> connection then the connection stays "silent" and
>> > > could
>> > > > be
>> > > > >> > >> closed
>> > > > >> > >> > on
>> > > > >> > >> > > > the
>> > > > >> > >> > > > > >> server side if it stays idle long enough --
>> whereas
>> > if
>> > > > we
>> > > > >> > start
>> > > > >> > >> > > > > injecting
>> > > > >> > >> > > > > >> re-authentication requests (as is done in the
>> > > high-level
>> > > > >> > >> approach)
>> > > > >> > >> > > > then
>> > > > >> > >> > > > > the
>> > > > >> > >> > > > > >> connection never goes completely silent and could
>> > (?)
>> > > > >> > >> potentially
>> > > > >> > >> > > > avoid
>> > > > >> > >> > > > > >> being closed due to idleness.
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> However, if we implement sever-side kill of
>> > > connections
>> > > > >> using
>> > > > >> > >> > > expired
>> > > > >> > >> > > > > >> credentials (which we agree is needed), then we
>> > might
>> > > > end
>> > > > >> up
>> > > > >> > >> with
>> > > > >> > >> > > the
>> > > > >> > >> > > > > >> broker killing connections that are sitting idle
>> for
>> > > > only
>> > > > >> a
>> > > > >> > >> short
>> > > > >> > >> > > > > period of
>> > > > >> > >> > > > > >> time.  For example, if we refresh the token on
>> the
>> > > > client
>> > > > >> > side
>> > > > >> > >> and
>> > > > >> > >> > > > tell
>> > > > >> > >> > > > > the
>> > > > >> > >> > > > > >> connection that it is eligible to be
>> > re-authenticated,
>> > > > >> then
>> > > > >> > it
>> > > > >> > >> is
>> > > > >> > >> > > > > >> conceivable that the connection might be sitting
>> > idle
>> > > at
>> > > > >> that
>> > > > >> > >> > point
>> > > > >> > >> > > > and
>> > > > >> > >> > > > > >> might not be used until after the token it is
>> > > currently
>> > > > >> using
>> > > > >> > >> > > expires.
>> > > > >> > >> > > > > The
>> > > > >> > >> > > > > >> server might kill the connection, and that would
>> > force
>> > > > the
>> > > > >> > >> client
>> > > > >> > >> > to
>> > > > >> > >> > > > > >> re-connect with a new connection (requiring TLS
>> > > > >> negotiation).
>> > > > >> > >> The
>> > > > >> > >> > > > > >> probability of this happening increases as the
>> token
>> > > > >> lifetime
>> > > > >> > >> > > > > decreases, of
>> > > > >> > >> > > > > >> course, and it can be offset by decreasing the
>> > window
>> > > > >> factor
>> > > > >> > >> (i.e.
>> > > > >> > >> > > > make
>> > > > >> > >> > > > > it
>> > > > >> > >> > > > > >> eligible for re-authenticate at 50% of the
>> lifetime
>> > > > rather
>> > > > >> > than
>> > > > >> > >> > 80%,
>> > > > >> > >> > > > for
>> > > > >> > >> > > > > >> example -- it would have to sit idle for longer
>> > before
>> > > > the
>> > > > >> > >> server
>> > > > >> > >> > > > tried
>> > > > >> > >> > > > > to
>> > > > >> > >> > > > > >> kill it).  We haven't implemented server-side
>> kill
>> > > yet,
>> > > > so
>> > > > >> > >> maybe
>> > > > >> > >> > we
>> > > > >> > >> > > > > could
>> > > > >> > >> > > > > >> make it intelligent and only kill the connection
>> if
>> > it
>> > > > is
>> > > > >> > used
>> > > > >> > >> > (for
>> > > > >> > >> > > > > >> anything except re-authentication) after the
>> > > expiration
>> > > > >> > time...
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> I also wonder about the ability to add retry into
>> > the
>> > > > >> > low-level
>> > > > >> > >> > > > > >> approach.  Do you think it would be possible?  It
>> > > > doesn't
>> > > > >> > seem
>> > > > >> > >> > like
>> > > > >> > >> > > it
>> > > > >> > >> > > > > to
>> > > > >> > >> > > > > >> me -- at least not without some big changes that
>> > would
>> > > > >> > >> eliminate
>> > > > >> > >> > > some
>> > > > >> > >> > > > of
>> > > > >> > >> > > > > >> the advantage of being able to reuse the existing
>> > > > >> > >> authentication
>> > > > >> > >> > > code.
>> > > > >> > >> > > > > The
>> > > > >> > >> > > > > >> reason I ask is because I think retry is
>> necessary.
>> > > It
>> > > > is
>> > > > >> > >> part of
>> > > > >> > >> > > how
>> > > > >> > >> > > > > >> refreshes work for both GSSAPI and OAUTHBEARER --
>> > they
>> > > > >> > refresh
>> > > > >> > >> > based
>> > > > >> > >> > > > on
>> > > > >> > >> > > > > >> some window factor (i.e. 80%) and implement
>> periodic
>> > > > retry
>> > > > >> > upon
>> > > > >> > >> > > > failure
>> > > > >> > >> > > > > so
>> > > > >> > >> > > > > >> that they can maximize the chances of having a
>> new
>> > > > >> credential
>> > > > >> > >> > > > available
>> > > > >> > >> > > > > for
>> > > > >> > >> > > > > >> any new connection attempt.  Without refresh we
>> > could
>> > > > end
>> > > > >> up
>> > > > >> > in
>> > > > >> > >> > the
>> > > > >> > >> > > > > >> situation where the connection still has some
>> > lifetime
>> > > > >> left
>> > > > >> > >> (10%,
>> > > > >> > >> > > 20%,
>> > > > >> > >> > > > > or
>> > > > >> > >> > > > > >> whatever) but it tries to re-authenticate and
>> cannot
>> > > > >> through
>> > > > >> > no
>> > > > >> > >> > > fault
>> > > > >> > >> > > > of
>> > > > >> > >> > > > > >> its own (i.e. token endpoint down, some Kerberos
>> > > > failure,
>> > > > >> > etc.)
>> > > > >> > >> > -=-
>> > > > >> > >> > > > the
>> > > > >> > >> > > > > >> connection is closed at that point, and it is
>> then
>> > > > unable
>> > > > >> to
>> > > > >> > >> > > reconnect
>> > > > >> > >> > > > > >> because of the same temporary problem.  We could
>> end
>> > > up
>> > > > >> with
>> > > > >> > an
>> > > > >> > >> > > > > especially
>> > > > >> > >> > > > > >> ill-timed, temporary outage in some non-Kafka
>> system
>> > > > >> (related
>> > > > >> > >> to
>> > > > >> > >> > > OAuth
>> > > > >> > >> > > > > or
>> > > > >> > >> > > > > >> Kerberos, or some LDAP directory) causing all
>> > clients
>> > > to
>> > > > >> be
>> > > > >> > >> kicked
>> > > > >> > >> > > off
>> > > > >> > >> > > > > the
>> > > > >> > >> > > > > >> cluster.  Retry capability seems to me to be the
>> way
>> > > to
>> > > > >> > >> mitigate
>> > > > >> > >> > > this
>> > > > >> > >> > > > > risk.
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> Anyway, that's it for now.  I really like the
>> > approach
>> > > > you
>> > > > >> > >> > outlined
>> > > > >> > >> > > --
>> > > > >> > >> > > > > at
>> > > > >> > >> > > > > >> least at this point based on my current
>> > understanding.
>> > > > I
>> > > > >> > will
>> > > > >> > >> > > > continue
>> > > > >> > >> > > > > to
>> > > > >> > >> > > > > >> dig in, and I may send more comments/questions.
>> But
>> > > for
>> > > > >> > now, I
>> > > > >> > >> > > think
>> > > > >> > >> > > > > the
>> > > > >> > >> > > > > >> lack of retry -- and my definitely-could-be-wrong
>> > > sense
>> > > > >> that
>> > > > >> > it
>> > > > >> > >> > > can't
>> > > > >> > >> > > > > >> easily be added -- is my biggest concern with
>> this
>> > > > >> low-level
>> > > > >> > >> > > approach.
>> > > > >> > >> > > > > >>
>> > > > >> > >> > > > > >> Ron
>> > > >
>
>

Reply via email to