You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@serf.apache.org by Peter Balogh <pe...@svnplus.com> on 2025/05/18 21:17:47 UTC
Re: 2FA prototype
Hi,
I'm moving this conversation from the subversion dev mailing list for now
I'm working on adding 2FA to subversion
I have a working PoC of this system, and I'd like to start submitting
patches.
The serf changes are attached, what is the process to get approval for this?
The patches, configs and scripts to make this work are publicly
available here:
https://pub.svnplus.com/repo/2fa/trunk
The implementation uses a special 499 http response code to request 2FA
auth, I have a working server config that serves this without any server
side changes https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
The system is running at https://2fa.svnplus.com/repo/2fa/trunk/, and it
works in the browser and the svn cli with the patches applied, but the
svn client does not yet save the cookie, so every command needs a 2fa
To access the demo system, use the username: user and password: pass
The 2FA QR code is displayed on the page
Please let me know, what you think
Best regards,
Peter
On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
> Hi,
>
> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>
> Hi,
>
> I'm working on a proof of concept to add multi factor
> authentication to
> subversion
> I have multiple directions, and I'd like to get some feedback from
> this
> group before I head down the wrong road
> Please let me know, if I should read up on any of these, I did not
> find
> any recent conversation about these topics
>
>
> I think this is a very interesting concept!
>
>
> 1. One option would be to extend the existing Basic auth with another
> challenge. This would support standard TOTP without external
> connections
> I couldn't find any standard way to communicating this through
> HTTP, my
> best solution would be to
>
> 1.A extend the 401 response with information that the system also
> needs
> a TOTP token
> I've only found the realm string I can use for this without modifying
> the serf library
>
> 1.B reject the username + password attempt with a different 401
> This would have to be handled inside the serf library
>
>
> I don't see a problem modifying Serf if it is needed. Several of the
> Subversion committers are also Serf committers and we can help there.
>
>
> 2. Provide an external login path instead Basic auth. This would
> open up
> using oauth or similar external providers, but a web based provider
> could be run besides svn as well
> The server would respond with a 30X response, and the cmdline could
> print the url for the user to open, login and return to the terminal
> after authentication
> This would feel less native, but pretty common these days
>
>
> I like this idea - I guess this would open up to for example Microsoft
> Entra.
>
> Make sure to use the standard baton/callback method to communicate the
> redirect URL to the client. This way GUI clients (for example
> TortoiseSVN) can implement a more "native" solution to the redirect.
>
>
> All of the solutions above would result in a HTTP cookie that
> would be
> stored encrypted in the auth folder, and sent with every
> subsequent request
>
>
> See existing discussions about storing the basic auth password in the
> auth folder. On Windows, there are APIs to encrypt the password linked
> to the user profile. In general no such on Unix, but I assume it could
> be stored in Gnome Keyring/Kwallet/GPG-agent.
>
>
> Do you have any thoughts or preferences about this?
> Do you see any technical or security issue with these?
>
>
> I know very little about the technical details of authentication on
> the http level but I think it would be god to adhere to existing
> standards as much as possible instead of inventing something unique to
> Subversion. For example it would be good if this can be done across a
> forward/reverse proxy.
>
> If this feature is enabled on a server, it would be impossible to
> authenticate with an older client. Don't know if this is a
> compatibility concern or not, but I think this addition would warrant
> new releases.
>
> Kind regards,
> Daniel
>
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 24. 5. 25 14:12, Daniel Sahlberg wrote:
> As I understand WWW-Authenticate, it is possible to add multiple
> authentications at the same time. If we would have a server-wide 2FA
> setting (ie, all users are required ot use 2FA), we could possibly combine
> steps 2 and 4 into a single step, saving a roundtrip to the server. (We
> don't need to know the user before requesting a TOTP - as long as we get
> the username we can verify it afterwards). Only maybe if it is difficult to
> send multiple Authorization: headers.
I think those multiple authentication types in WWW-Authenticate are
meant to be alternatives, not a sequence, the client picks the scheme it
supports. I have no clue what happens if you send multiple Authorization
headers. You could invent combined schemes, e.g., "Basic+TOTP" and
define how the TOTP response is encoded in the Authorization header
along with the other credentials, but that would kill generic DAV clients.
And let's not forget that one can browse Subversion repositories ...
that's a case that we've not discussed yet. Heh, imagine mod_dav_svn, I
mean mod_authn_totp, generating HTML to request a second factor. Ouch. :)
-- Brane
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 24. 5. 25 14:12, Daniel Sahlberg wrote:
> As I understand WWW-Authenticate, it is possible to add multiple
> authentications at the same time. If we would have a server-wide 2FA
> setting (ie, all users are required ot use 2FA), we could possibly combine
> steps 2 and 4 into a single step, saving a roundtrip to the server. (We
> don't need to know the user before requesting a TOTP - as long as we get
> the username we can verify it afterwards). Only maybe if it is difficult to
> send multiple Authorization: headers.
I think those multiple authentication types in WWW-Authenticate are
meant to be alternatives, not a sequence, the client picks the scheme it
supports. I have no clue what happens if you send multiple Authorization
headers. You could invent combined schemes, e.g., "Basic+TOTP" and
define how the TOTP response is encoded in the Authorization header
along with the other credentials, but that would kill generic DAV clients.
And let's not forget that one can browse Subversion repositories ...
that's a case that we've not discussed yet. Heh, imagine mod_dav_svn, I
mean mod_authn_totp, generating HTML to request a second factor. Ouch. :)
-- Brane
Re: 2FA prototype
Posted by Daniel Sahlberg <da...@gmail.com>.
Den lör 24 maj 2025 kl 14:01 skrev Branko Čibej <br...@apache.org>:
> On 23. 5. 25 23:48, Peter Balogh wrote:
>
> Hi,
>
> The reason I choose the 499 status code, that it was the cleanest way to
> reroute the 2FA case in auth.c dispatch_auth function
> Hard-coding the 401 can also accomplish this
> But without that, I have two directions I can take, and I'd appreciate
> some insight, what should I try next:
>
> 1.
> I can provide a response with 401 status and valid WWW-Authenticate header
> where I control the realm string
> I can use that to intercept the 2FA request in
> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the 2FA
> input
> That combined with bearer token, that we return could work without
> modifying serf
>
> 2.
> I can introduce a new serf__authn_scheme_t, and have a cleaner
> implementation, but it means serf would have an unofficial auth scheme
> implementation
>
> I'm all for doing the right thing, working out how to extend the RFC, but
> I have 0 knowledge or experience doing that
> I'm happy to help any way I can, but I'd rather not wait for months,
> before implementing this :)
>
> What do you think, what route should I explore next?
> Do I have a change to get the 1. version approved by the svn community?
> Do I have a change to get the 2. version approved by the serf community?
> :)
>
>
>
> I guess that you realise by now that there's a large overlap between the
> two. :)
>
> I just read through RFC 7235 and the way I read this, It's perfectly OK
> and blessed from on high to use status 401 to require a multi-factor token.
> The interaction would look like this:
>
>
> 1. Client: sends request to URL
> 2. Server: responds with 401 + WWW-Authenticate for initial
> username+password authentication, with Subversion's realm=... parameter
> 3. Client: sends to URL + Authorization with username and password
>
> (This is how it works now, regardless of authentication type, and the
> client continues to send further requests with the same Authorization
> header. In the multi-factor scenario, what happens next is; I'll illustrate
> with TOTP):
>
> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
> 5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based
> PIN)
> 6. Server: processes the request and responds with a generated token
> in a header (or cookies). The token could be a JWT if we want more control
> or a random token as suggested by Greg.
> 7. Client sends "Authorization: Bearer <token>" with further requests.
>
>
> This works for other 2FA schemes, too; for example, in step 4 the server
> could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==,
> realm=..." and in step 5 the client would respond with "Authenticate:
> SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to
> generate the token.
>
> This does not require any changes in Serf and is, as far as I can see,
> compliant with RFC 7235. But you do need an authentication handler on the
> server side to handle the second (and third and fourth... there's no reason
> this would be limited to two factors). Also if you use some random token,
> the authn handler has to store it and eventually invalidate it; a JWT
> contains its expiration time, removing the need for a token database on the
> server, but it's a bit of a pain to implement.
>
> On the Subversion client side, libsvn_ra_serf might have to grow another
> hook for multi-factor callbacks, and we'd need another authentication
> provider that would store the shared-secret per realm, similar to what the
> username provider does now.
>
This sounds very good to me, much like the understanding I have at the
moment.
As I understand WWW-Authenticate, it is possible to add multiple
authentications at the same time. If we would have a server-wide 2FA
setting (ie, all users are required ot use 2FA), we could possibly combine
steps 2 and 4 into a single step, saving a roundtrip to the server. (We
don't need to know the user before requesting a TOTP - as long as we get
the username we can verify it afterwards). Only maybe if it is difficult to
send multiple Authorization: headers.
Kind regards,
Daniel
>
>
>
> Best regards,
> Peter
>
> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>
> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>
> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>
> <pe...@svnplus.com>:
>
> Hi,
>
> So basically the patch becomes this
> I can't say I like the actual branch condition, but I'm open to
> suggestions :)
>
> Hi,
>
> I have not studied the patches in detail but I'm not so sure if I like the
> idea of Serf special-casing / hardcoding a custom response reason. I feel
> it would be better to offloading this to Subversion since we control both
> ends there.
>
>
>
> I agree. Serf is a general-purpose HTTP client, what we're talking about
> here is application-level behaviour. Serf already offloads authentication
> to the application, I also can't see a reason why this would be
> special-cased in Serf.
>
> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header
> - I don't know if it would be possible to use this to send the challenge.
>
>
> I have to read up on WWW-Authenticate. ISTR that aside from telling the
> client /how/ to authenticate, it's there also support complex
> authentication processes.
>
> The response could then be added as a header field. Would it be possible
> for the server to return a bearer token (= more or less the same as a
> Set-Cookie) that we could store client-side to include on future requests?
>
>
> I'm surprised that multi-step challenge/response mechanism isn't already
> standardised in HTTP. True, all the multi-factor schemes I've used to date
> are for authentication flow in browsers, where the server presents a user
> interface. For headless cases, things like API tokens tend to be generated
> in advance through an out of band channel (again, usually through a UI in a
> browser). App tokens are, again, not multi-factor authentication.
>
> Maybe we will have to invent an HTTP workflow for this, but let's not go
> it alone. This is, after all, the ASF and there are a few people around
> that are ... quite knowledgeable about HTTP. I suggest we consult. Worst
> case, there may be an IETF RFC waiting to be written.
>
> -- Brane
>
>
> P.S.: I say "worst case" because it should've been written long ago
> instead of people using status 499 and stuff like that.
>
>
>
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 24. 5. 25 21:26, Peter Balogh wrote:
> Hi,
>
> Sounds like a plan! But I still don't see how I can do this without
> modifying serf
> The TOTP scheme have to be in the serf_authn_schemes array, and that's
> internal to serf
> Am I missing something?
Ah, you're right... bummer. I somehow remembered users could register
authn schemes, but apparently not. That's unfortunate...
> JWT is easy to detect and handle, this can be added easily in my
> opinion, but I'll take a look once we get there :)
JWT is far from simple, actually. When you factor in encrypted tokens
and refresh tokens, it becomes not exactly trivial to support. But,
sure, for basic usage, you only have to be able to generate a HMAC
signature. And parse JSON. HTTPd modules should be able to do that, or
some CGI script for a proof of concept (python-cryptography certainly can).
> I'll keep sending the same token with a set cookie, that serf and svn
> can ignore to make browsers work
Good idea.
> Best regards,
> Peter
>
> On 2025. 05. 24. 14:01, Branko Čibej wrote:
>> On 23. 5. 25 23:48, Peter Balogh wrote:
>>> Hi,
>>>
>>> The reason I choose the 499 status code, that it was the cleanest
>>> way to reroute the 2FA case in auth.c dispatch_auth function
>>> Hard-coding the 401 can also accomplish this
>>> But without that, I have two directions I can take, and I'd
>>> appreciate some insight, what should I try next:
>>>
>>> 1.
>>> I can provide a response with 401 status and valid WWW-Authenticate
>>> header where I control the realm string
>>> I can use that to intercept the 2FA request in
>>> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do
>>> the 2FA input
>>> That combined with bearer token, that we return could work without
>>> modifying serf
>>>
>>> 2.
>>> I can introduce a new serf__authn_scheme_t, and have a cleaner
>>> implementation, but it means serf would have an unofficial auth
>>> scheme implementation
>>>
>>> I'm all for doing the right thing, working out how to extend the
>>> RFC, but I have 0 knowledge or experience doing that
>>> I'm happy to help any way I can, but I'd rather not wait for months,
>>> before implementing this :)
>>>
>>> What do you think, what route should I explore next?
>>> Do I have a change to get the 1. version approved by the svn community?
>>> Do I have a change to get the 2. version approved by the serf
>>> community? :)
>>
>>
>> I guess that you realise by now that there's a large overlap between
>> the two. :)
>>
>> I just read through RFC 7235 and the way I read this, It's perfectly
>> OK and blessed from on high to use status 401 to require a
>> multi-factor token. The interaction would look like this:
>>
>> 1. Client: sends request to URL
>> 2. Server: responds with 401 + WWW-Authenticate for initial
>> username+password authentication, with Subversion's realm=...
>> parameter
>> 3. Client: sends to URL + Authorization with username and password
>>
>> (This is how it works now, regardless of authentication type, and
>> the client continues to send further requests with the same
>> Authorization header. In the multi-factor scenario, what happens
>> next is; I'll illustrate with TOTP):
>>
>> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
>> 5. Client: sends to URL + "Authorization: TOTP 123456" (the
>> time-based PIN)
>> 6. Server: processes the request and responds with a generated token
>> in a header (or cookies). The token could be a JWT if we want more
>> control or a random token as suggested by Greg.
>> 7. Client sends "Authorization: Bearer <token>" with further requests.
>>
>>
>> This works for other 2FA schemes, too; for example, in step 4 the
>> server could respond with "WWW-Authenticate: SCRAM
>> challenge=Y2hhbGxlbmdlPw==, realm=..." and in step 5 the client would
>> respond with "Authenticate: SCRAM cmVzcG9uc2Uh", using the shared
>> secret and the challenge to generate the token.
>>
>> This does not require any changes in Serf and is, as far as I can
>> see, compliant with RFC 7235. But you do need an authentication
>> handler on the server side to handle the second (and third and
>> fourth... there's no reason this would be limited to two factors).
>> Also if you use some random token, the authn handler has to store it
>> and eventually invalidate it; a JWT contains its expiration time,
>> removing the need for a token database on the server, but it's a bit
>> of a pain to implement.
>>
>> On the Subversion client side, libsvn_ra_serf might have to grow
>> another hook for multi-factor callbacks, and we'd need another
>> authentication provider that would store the shared-secret per realm,
>> similar to what the username provider does now.
>>
>>
>>>
>>> Best regards,
>>> Peter
>>>
>>> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>>>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> So basically the patch becomes this
>>>>>> I can't say I like the actual branch condition, but I'm open to
>>>>>> suggestions :)
>>>>>>
>>>>> Hi,
>>>>>
>>>>> I have not studied the patches in detail but I'm not so sure if I
>>>>> like the
>>>>> idea of Serf special-casing / hardcoding a custom response reason.
>>>>> I feel
>>>>> it would be better to offloading this to Subversion since we
>>>>> control both
>>>>> ends there.
>>>>
>>>>
>>>> I agree. Serf is a general-purpose HTTP client, what we're talking
>>>> about here is application-level behaviour. Serf already offloads
>>>> authentication to the application, I also can't see a reason why
>>>> this would be special-cased in Serf.
>>>>
>>>>> Also, RFC7235 [1] require a 401 response to send a
>>>>> WWW-Authenticate header
>>>>> - I don't know if it would be possible to use this to send the
>>>>> challenge.
>>>>
>>>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>>>> the client /how/ to authenticate, it's there also support complex
>>>> authentication processes.
>>>>
>>>>> The response could then be added as a header field. Would it be
>>>>> possible
>>>>> for the server to return a bearer token (= more or less the same as a
>>>>> Set-Cookie) that we could store client-side to include on future
>>>>> requests?
>>>>
>>>> I'm surprised that multi-step challenge/response mechanism isn't
>>>> already standardised in HTTP. True, all the multi-factor schemes
>>>> I've used to date are for authentication flow in browsers, where
>>>> the server presents a user interface. For headless cases, things
>>>> like API tokens tend to be generated in advance through an out of
>>>> band channel (again, usually through a UI in a browser). App tokens
>>>> are, again, not multi-factor authentication.
>>>>
>>>> Maybe we will have to invent an HTTP workflow for this, but let's
>>>> not go it alone. This is, after all, the ASF and there are a few
>>>> people around that are ... quite knowledgeable about HTTP. I
>>>> suggest we consult. Worst case, there may be an IETF RFC waiting to
>>>> be written.
>>>>
>>>> -- Brane
>>>>
>>>>
>>>> P.S.: I say "worst case" because it should've been written long ago
>>>> instead of people using status 499 and stuff like that.
>>
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 24. 5. 25 21:26, Peter Balogh wrote:
> Hi,
>
> Sounds like a plan! But I still don't see how I can do this without
> modifying serf
> The TOTP scheme have to be in the serf_authn_schemes array, and that's
> internal to serf
> Am I missing something?
Ah, you're right... bummer. I somehow remembered users could register
authn schemes, but apparently not. That's unfortunate...
> JWT is easy to detect and handle, this can be added easily in my
> opinion, but I'll take a look once we get there :)
JWT is far from simple, actually. When you factor in encrypted tokens
and refresh tokens, it becomes not exactly trivial to support. But,
sure, for basic usage, you only have to be able to generate a HMAC
signature. And parse JSON. HTTPd modules should be able to do that, or
some CGI script for a proof of concept (python-cryptography certainly can).
> I'll keep sending the same token with a set cookie, that serf and svn
> can ignore to make browsers work
Good idea.
> Best regards,
> Peter
>
> On 2025. 05. 24. 14:01, Branko Čibej wrote:
>> On 23. 5. 25 23:48, Peter Balogh wrote:
>>> Hi,
>>>
>>> The reason I choose the 499 status code, that it was the cleanest
>>> way to reroute the 2FA case in auth.c dispatch_auth function
>>> Hard-coding the 401 can also accomplish this
>>> But without that, I have two directions I can take, and I'd
>>> appreciate some insight, what should I try next:
>>>
>>> 1.
>>> I can provide a response with 401 status and valid WWW-Authenticate
>>> header where I control the realm string
>>> I can use that to intercept the 2FA request in
>>> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do
>>> the 2FA input
>>> That combined with bearer token, that we return could work without
>>> modifying serf
>>>
>>> 2.
>>> I can introduce a new serf__authn_scheme_t, and have a cleaner
>>> implementation, but it means serf would have an unofficial auth
>>> scheme implementation
>>>
>>> I'm all for doing the right thing, working out how to extend the
>>> RFC, but I have 0 knowledge or experience doing that
>>> I'm happy to help any way I can, but I'd rather not wait for months,
>>> before implementing this :)
>>>
>>> What do you think, what route should I explore next?
>>> Do I have a change to get the 1. version approved by the svn community?
>>> Do I have a change to get the 2. version approved by the serf
>>> community? :)
>>
>>
>> I guess that you realise by now that there's a large overlap between
>> the two. :)
>>
>> I just read through RFC 7235 and the way I read this, It's perfectly
>> OK and blessed from on high to use status 401 to require a
>> multi-factor token. The interaction would look like this:
>>
>> 1. Client: sends request to URL
>> 2. Server: responds with 401 + WWW-Authenticate for initial
>> username+password authentication, with Subversion's realm=...
>> parameter
>> 3. Client: sends to URL + Authorization with username and password
>>
>> (This is how it works now, regardless of authentication type, and
>> the client continues to send further requests with the same
>> Authorization header. In the multi-factor scenario, what happens
>> next is; I'll illustrate with TOTP):
>>
>> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
>> 5. Client: sends to URL + "Authorization: TOTP 123456" (the
>> time-based PIN)
>> 6. Server: processes the request and responds with a generated token
>> in a header (or cookies). The token could be a JWT if we want more
>> control or a random token as suggested by Greg.
>> 7. Client sends "Authorization: Bearer <token>" with further requests.
>>
>>
>> This works for other 2FA schemes, too; for example, in step 4 the
>> server could respond with "WWW-Authenticate: SCRAM
>> challenge=Y2hhbGxlbmdlPw==, realm=..." and in step 5 the client would
>> respond with "Authenticate: SCRAM cmVzcG9uc2Uh", using the shared
>> secret and the challenge to generate the token.
>>
>> This does not require any changes in Serf and is, as far as I can
>> see, compliant with RFC 7235. But you do need an authentication
>> handler on the server side to handle the second (and third and
>> fourth... there's no reason this would be limited to two factors).
>> Also if you use some random token, the authn handler has to store it
>> and eventually invalidate it; a JWT contains its expiration time,
>> removing the need for a token database on the server, but it's a bit
>> of a pain to implement.
>>
>> On the Subversion client side, libsvn_ra_serf might have to grow
>> another hook for multi-factor callbacks, and we'd need another
>> authentication provider that would store the shared-secret per realm,
>> similar to what the username provider does now.
>>
>>
>>>
>>> Best regards,
>>> Peter
>>>
>>> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>>>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> So basically the patch becomes this
>>>>>> I can't say I like the actual branch condition, but I'm open to
>>>>>> suggestions :)
>>>>>>
>>>>> Hi,
>>>>>
>>>>> I have not studied the patches in detail but I'm not so sure if I
>>>>> like the
>>>>> idea of Serf special-casing / hardcoding a custom response reason.
>>>>> I feel
>>>>> it would be better to offloading this to Subversion since we
>>>>> control both
>>>>> ends there.
>>>>
>>>>
>>>> I agree. Serf is a general-purpose HTTP client, what we're talking
>>>> about here is application-level behaviour. Serf already offloads
>>>> authentication to the application, I also can't see a reason why
>>>> this would be special-cased in Serf.
>>>>
>>>>> Also, RFC7235 [1] require a 401 response to send a
>>>>> WWW-Authenticate header
>>>>> - I don't know if it would be possible to use this to send the
>>>>> challenge.
>>>>
>>>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>>>> the client /how/ to authenticate, it's there also support complex
>>>> authentication processes.
>>>>
>>>>> The response could then be added as a header field. Would it be
>>>>> possible
>>>>> for the server to return a bearer token (= more or less the same as a
>>>>> Set-Cookie) that we could store client-side to include on future
>>>>> requests?
>>>>
>>>> I'm surprised that multi-step challenge/response mechanism isn't
>>>> already standardised in HTTP. True, all the multi-factor schemes
>>>> I've used to date are for authentication flow in browsers, where
>>>> the server presents a user interface. For headless cases, things
>>>> like API tokens tend to be generated in advance through an out of
>>>> band channel (again, usually through a UI in a browser). App tokens
>>>> are, again, not multi-factor authentication.
>>>>
>>>> Maybe we will have to invent an HTTP workflow for this, but let's
>>>> not go it alone. This is, after all, the ASF and there are a few
>>>> people around that are ... quite knowledgeable about HTTP. I
>>>> suggest we consult. Worst case, there may be an IETF RFC waiting to
>>>> be written.
>>>>
>>>> -- Brane
>>>>
>>>>
>>>> P.S.: I say "worst case" because it should've been written long ago
>>>> instead of people using status 499 and stuff like that.
>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Sounds like a plan! But I still don't see how I can do this without
modifying serf
The TOTP scheme have to be in the serf_authn_schemes array, and that's
internal to serf
Am I missing something?
JWT is easy to detect and handle, this can be added easily in my
opinion, but I'll take a look once we get there :)
I'll keep sending the same token with a set cookie, that serf and svn
can ignore to make browsers work
Best regards,
Peter
On 2025. 05. 24. 14:01, Branko Čibej wrote:
> On 23. 5. 25 23:48, Peter Balogh wrote:
>> Hi,
>>
>> The reason I choose the 499 status code, that it was the cleanest way
>> to reroute the 2FA case in auth.c dispatch_auth function
>> Hard-coding the 401 can also accomplish this
>> But without that, I have two directions I can take, and I'd
>> appreciate some insight, what should I try next:
>>
>> 1.
>> I can provide a response with 401 status and valid WWW-Authenticate
>> header where I control the realm string
>> I can use that to intercept the 2FA request in
>> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do
>> the 2FA input
>> That combined with bearer token, that we return could work without
>> modifying serf
>>
>> 2.
>> I can introduce a new serf__authn_scheme_t, and have a cleaner
>> implementation, but it means serf would have an unofficial auth
>> scheme implementation
>>
>> I'm all for doing the right thing, working out how to extend the RFC,
>> but I have 0 knowledge or experience doing that
>> I'm happy to help any way I can, but I'd rather not wait for months,
>> before implementing this :)
>>
>> What do you think, what route should I explore next?
>> Do I have a change to get the 1. version approved by the svn community?
>> Do I have a change to get the 2. version approved by the serf
>> community? :)
>
>
> I guess that you realise by now that there's a large overlap between
> the two. :)
>
> I just read through RFC 7235 and the way I read this, It's perfectly
> OK and blessed from on high to use status 401 to require a
> multi-factor token. The interaction would look like this:
>
> 1. Client: sends request to URL
> 2. Server: responds with 401 + WWW-Authenticate for initial
> username+password authentication, with Subversion's realm=...
> parameter
> 3. Client: sends to URL + Authorization with username and password
>
> (This is how it works now, regardless of authentication type, and
> the client continues to send further requests with the same
> Authorization header. In the multi-factor scenario, what happens
> next is; I'll illustrate with TOTP):
>
> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
> 5. Client: sends to URL + "Authorization: TOTP 123456" (the
> time-based PIN)
> 6. Server: processes the request and responds with a generated token
> in a header (or cookies). The token could be a JWT if we want more
> control or a random token as suggested by Greg.
> 7. Client sends "Authorization: Bearer <token>" with further requests.
>
>
> This works for other 2FA schemes, too; for example, in step 4 the
> server could respond with "WWW-Authenticate: SCRAM
> challenge=Y2hhbGxlbmdlPw==, realm=..." and in step 5 the client would
> respond with "Authenticate: SCRAM cmVzcG9uc2Uh", using the shared
> secret and the challenge to generate the token.
>
> This does not require any changes in Serf and is, as far as I can see,
> compliant with RFC 7235. But you do need an authentication handler on
> the server side to handle the second (and third and fourth... there's
> no reason this would be limited to two factors). Also if you use some
> random token, the authn handler has to store it and eventually
> invalidate it; a JWT contains its expiration time, removing the need
> for a token database on the server, but it's a bit of a pain to implement.
>
> On the Subversion client side, libsvn_ra_serf might have to grow
> another hook for multi-factor callbacks, and we'd need another
> authentication provider that would store the shared-secret per realm,
> similar to what the username provider does now.
>
>
>>
>> Best regards,
>> Peter
>>
>> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>>
>>>>> Hi,
>>>>>
>>>>> So basically the patch becomes this
>>>>> I can't say I like the actual branch condition, but I'm open to
>>>>> suggestions :)
>>>>>
>>>> Hi,
>>>>
>>>> I have not studied the patches in detail but I'm not so sure if I
>>>> like the
>>>> idea of Serf special-casing / hardcoding a custom response reason.
>>>> I feel
>>>> it would be better to offloading this to Subversion since we
>>>> control both
>>>> ends there.
>>>
>>>
>>> I agree. Serf is a general-purpose HTTP client, what we're talking
>>> about here is application-level behaviour. Serf already offloads
>>> authentication to the application, I also can't see a reason why
>>> this would be special-cased in Serf.
>>>
>>>> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
>>>> header
>>>> - I don't know if it would be possible to use this to send the
>>>> challenge.
>>>
>>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>>> the client /how/ to authenticate, it's there also support complex
>>> authentication processes.
>>>
>>>> The response could then be added as a header field. Would it be
>>>> possible
>>>> for the server to return a bearer token (= more or less the same as a
>>>> Set-Cookie) that we could store client-side to include on future
>>>> requests?
>>>
>>> I'm surprised that multi-step challenge/response mechanism isn't
>>> already standardised in HTTP. True, all the multi-factor schemes
>>> I've used to date are for authentication flow in browsers, where the
>>> server presents a user interface. For headless cases, things like
>>> API tokens tend to be generated in advance through an out of band
>>> channel (again, usually through a UI in a browser). App tokens are,
>>> again, not multi-factor authentication.
>>>
>>> Maybe we will have to invent an HTTP workflow for this, but let's
>>> not go it alone. This is, after all, the ASF and there are a few
>>> people around that are ... quite knowledgeable about HTTP. I suggest
>>> we consult. Worst case, there may be an IETF RFC waiting to be written.
>>>
>>> -- Brane
>>>
>>>
>>> P.S.: I say "worst case" because it should've been written long ago
>>> instead of people using status 499 and stuff like that.
>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Sounds like a plan! But I still don't see how I can do this without
modifying serf
The TOTP scheme have to be in the serf_authn_schemes array, and that's
internal to serf
Am I missing something?
JWT is easy to detect and handle, this can be added easily in my
opinion, but I'll take a look once we get there :)
I'll keep sending the same token with a set cookie, that serf and svn
can ignore to make browsers work
Best regards,
Peter
On 2025. 05. 24. 14:01, Branko Čibej wrote:
> On 23. 5. 25 23:48, Peter Balogh wrote:
>> Hi,
>>
>> The reason I choose the 499 status code, that it was the cleanest way
>> to reroute the 2FA case in auth.c dispatch_auth function
>> Hard-coding the 401 can also accomplish this
>> But without that, I have two directions I can take, and I'd
>> appreciate some insight, what should I try next:
>>
>> 1.
>> I can provide a response with 401 status and valid WWW-Authenticate
>> header where I control the realm string
>> I can use that to intercept the 2FA request in
>> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do
>> the 2FA input
>> That combined with bearer token, that we return could work without
>> modifying serf
>>
>> 2.
>> I can introduce a new serf__authn_scheme_t, and have a cleaner
>> implementation, but it means serf would have an unofficial auth
>> scheme implementation
>>
>> I'm all for doing the right thing, working out how to extend the RFC,
>> but I have 0 knowledge or experience doing that
>> I'm happy to help any way I can, but I'd rather not wait for months,
>> before implementing this :)
>>
>> What do you think, what route should I explore next?
>> Do I have a change to get the 1. version approved by the svn community?
>> Do I have a change to get the 2. version approved by the serf
>> community? :)
>
>
> I guess that you realise by now that there's a large overlap between
> the two. :)
>
> I just read through RFC 7235 and the way I read this, It's perfectly
> OK and blessed from on high to use status 401 to require a
> multi-factor token. The interaction would look like this:
>
> 1. Client: sends request to URL
> 2. Server: responds with 401 + WWW-Authenticate for initial
> username+password authentication, with Subversion's realm=...
> parameter
> 3. Client: sends to URL + Authorization with username and password
>
> (This is how it works now, regardless of authentication type, and
> the client continues to send further requests with the same
> Authorization header. In the multi-factor scenario, what happens
> next is; I'll illustrate with TOTP):
>
> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
> 5. Client: sends to URL + "Authorization: TOTP 123456" (the
> time-based PIN)
> 6. Server: processes the request and responds with a generated token
> in a header (or cookies). The token could be a JWT if we want more
> control or a random token as suggested by Greg.
> 7. Client sends "Authorization: Bearer <token>" with further requests.
>
>
> This works for other 2FA schemes, too; for example, in step 4 the
> server could respond with "WWW-Authenticate: SCRAM
> challenge=Y2hhbGxlbmdlPw==, realm=..." and in step 5 the client would
> respond with "Authenticate: SCRAM cmVzcG9uc2Uh", using the shared
> secret and the challenge to generate the token.
>
> This does not require any changes in Serf and is, as far as I can see,
> compliant with RFC 7235. But you do need an authentication handler on
> the server side to handle the second (and third and fourth... there's
> no reason this would be limited to two factors). Also if you use some
> random token, the authn handler has to store it and eventually
> invalidate it; a JWT contains its expiration time, removing the need
> for a token database on the server, but it's a bit of a pain to implement.
>
> On the Subversion client side, libsvn_ra_serf might have to grow
> another hook for multi-factor callbacks, and we'd need another
> authentication provider that would store the shared-secret per realm,
> similar to what the username provider does now.
>
>
>>
>> Best regards,
>> Peter
>>
>> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>>
>>>>> Hi,
>>>>>
>>>>> So basically the patch becomes this
>>>>> I can't say I like the actual branch condition, but I'm open to
>>>>> suggestions :)
>>>>>
>>>> Hi,
>>>>
>>>> I have not studied the patches in detail but I'm not so sure if I
>>>> like the
>>>> idea of Serf special-casing / hardcoding a custom response reason.
>>>> I feel
>>>> it would be better to offloading this to Subversion since we
>>>> control both
>>>> ends there.
>>>
>>>
>>> I agree. Serf is a general-purpose HTTP client, what we're talking
>>> about here is application-level behaviour. Serf already offloads
>>> authentication to the application, I also can't see a reason why
>>> this would be special-cased in Serf.
>>>
>>>> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
>>>> header
>>>> - I don't know if it would be possible to use this to send the
>>>> challenge.
>>>
>>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>>> the client /how/ to authenticate, it's there also support complex
>>> authentication processes.
>>>
>>>> The response could then be added as a header field. Would it be
>>>> possible
>>>> for the server to return a bearer token (= more or less the same as a
>>>> Set-Cookie) that we could store client-side to include on future
>>>> requests?
>>>
>>> I'm surprised that multi-step challenge/response mechanism isn't
>>> already standardised in HTTP. True, all the multi-factor schemes
>>> I've used to date are for authentication flow in browsers, where the
>>> server presents a user interface. For headless cases, things like
>>> API tokens tend to be generated in advance through an out of band
>>> channel (again, usually through a UI in a browser). App tokens are,
>>> again, not multi-factor authentication.
>>>
>>> Maybe we will have to invent an HTTP workflow for this, but let's
>>> not go it alone. This is, after all, the ASF and there are a few
>>> people around that are ... quite knowledgeable about HTTP. I suggest
>>> we consult. Worst case, there may be an IETF RFC waiting to be written.
>>>
>>> -- Brane
>>>
>>>
>>> P.S.: I say "worst case" because it should've been written long ago
>>> instead of people using status 499 and stuff like that.
>
Re: 2FA prototype
Posted by Daniel Sahlberg <da...@gmail.com>.
Den lör 24 maj 2025 kl 14:01 skrev Branko Čibej <br...@apache.org>:
> On 23. 5. 25 23:48, Peter Balogh wrote:
>
> Hi,
>
> The reason I choose the 499 status code, that it was the cleanest way to
> reroute the 2FA case in auth.c dispatch_auth function
> Hard-coding the 401 can also accomplish this
> But without that, I have two directions I can take, and I'd appreciate
> some insight, what should I try next:
>
> 1.
> I can provide a response with 401 status and valid WWW-Authenticate header
> where I control the realm string
> I can use that to intercept the 2FA request in
> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the 2FA
> input
> That combined with bearer token, that we return could work without
> modifying serf
>
> 2.
> I can introduce a new serf__authn_scheme_t, and have a cleaner
> implementation, but it means serf would have an unofficial auth scheme
> implementation
>
> I'm all for doing the right thing, working out how to extend the RFC, but
> I have 0 knowledge or experience doing that
> I'm happy to help any way I can, but I'd rather not wait for months,
> before implementing this :)
>
> What do you think, what route should I explore next?
> Do I have a change to get the 1. version approved by the svn community?
> Do I have a change to get the 2. version approved by the serf community?
> :)
>
>
>
> I guess that you realise by now that there's a large overlap between the
> two. :)
>
> I just read through RFC 7235 and the way I read this, It's perfectly OK
> and blessed from on high to use status 401 to require a multi-factor token.
> The interaction would look like this:
>
>
> 1. Client: sends request to URL
> 2. Server: responds with 401 + WWW-Authenticate for initial
> username+password authentication, with Subversion's realm=... parameter
> 3. Client: sends to URL + Authorization with username and password
>
> (This is how it works now, regardless of authentication type, and the
> client continues to send further requests with the same Authorization
> header. In the multi-factor scenario, what happens next is; I'll illustrate
> with TOTP):
>
> 4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
> 5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based
> PIN)
> 6. Server: processes the request and responds with a generated token
> in a header (or cookies). The token could be a JWT if we want more control
> or a random token as suggested by Greg.
> 7. Client sends "Authorization: Bearer <token>" with further requests.
>
>
> This works for other 2FA schemes, too; for example, in step 4 the server
> could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==,
> realm=..." and in step 5 the client would respond with "Authenticate:
> SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to
> generate the token.
>
> This does not require any changes in Serf and is, as far as I can see,
> compliant with RFC 7235. But you do need an authentication handler on the
> server side to handle the second (and third and fourth... there's no reason
> this would be limited to two factors). Also if you use some random token,
> the authn handler has to store it and eventually invalidate it; a JWT
> contains its expiration time, removing the need for a token database on the
> server, but it's a bit of a pain to implement.
>
> On the Subversion client side, libsvn_ra_serf might have to grow another
> hook for multi-factor callbacks, and we'd need another authentication
> provider that would store the shared-secret per realm, similar to what the
> username provider does now.
>
This sounds very good to me, much like the understanding I have at the
moment.
As I understand WWW-Authenticate, it is possible to add multiple
authentications at the same time. If we would have a server-wide 2FA
setting (ie, all users are required ot use 2FA), we could possibly combine
steps 2 and 4 into a single step, saving a roundtrip to the server. (We
don't need to know the user before requesting a TOTP - as long as we get
the username we can verify it afterwards). Only maybe if it is difficult to
send multiple Authorization: headers.
Kind regards,
Daniel
>
>
>
> Best regards,
> Peter
>
> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>
> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>
> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>
> <pe...@svnplus.com>:
>
> Hi,
>
> So basically the patch becomes this
> I can't say I like the actual branch condition, but I'm open to
> suggestions :)
>
> Hi,
>
> I have not studied the patches in detail but I'm not so sure if I like the
> idea of Serf special-casing / hardcoding a custom response reason. I feel
> it would be better to offloading this to Subversion since we control both
> ends there.
>
>
>
> I agree. Serf is a general-purpose HTTP client, what we're talking about
> here is application-level behaviour. Serf already offloads authentication
> to the application, I also can't see a reason why this would be
> special-cased in Serf.
>
> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header
> - I don't know if it would be possible to use this to send the challenge.
>
>
> I have to read up on WWW-Authenticate. ISTR that aside from telling the
> client /how/ to authenticate, it's there also support complex
> authentication processes.
>
> The response could then be added as a header field. Would it be possible
> for the server to return a bearer token (= more or less the same as a
> Set-Cookie) that we could store client-side to include on future requests?
>
>
> I'm surprised that multi-step challenge/response mechanism isn't already
> standardised in HTTP. True, all the multi-factor schemes I've used to date
> are for authentication flow in browsers, where the server presents a user
> interface. For headless cases, things like API tokens tend to be generated
> in advance through an out of band channel (again, usually through a UI in a
> browser). App tokens are, again, not multi-factor authentication.
>
> Maybe we will have to invent an HTTP workflow for this, but let's not go
> it alone. This is, after all, the ASF and there are a few people around
> that are ... quite knowledgeable about HTTP. I suggest we consult. Worst
> case, there may be an IETF RFC waiting to be written.
>
> -- Brane
>
>
> P.S.: I say "worst case" because it should've been written long ago
> instead of people using status 499 and stuff like that.
>
>
>
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 23. 5. 25 23:48, Peter Balogh wrote:
> Hi,
>
> The reason I choose the 499 status code, that it was the cleanest way
> to reroute the 2FA case in auth.c dispatch_auth function
> Hard-coding the 401 can also accomplish this
> But without that, I have two directions I can take, and I'd appreciate
> some insight, what should I try next:
>
> 1.
> I can provide a response with 401 status and valid WWW-Authenticate
> header where I control the realm string
> I can use that to intercept the 2FA request in
> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the
> 2FA input
> That combined with bearer token, that we return could work without
> modifying serf
>
> 2.
> I can introduce a new serf__authn_scheme_t, and have a cleaner
> implementation, but it means serf would have an unofficial auth scheme
> implementation
>
> I'm all for doing the right thing, working out how to extend the RFC,
> but I have 0 knowledge or experience doing that
> I'm happy to help any way I can, but I'd rather not wait for months,
> before implementing this :)
>
> What do you think, what route should I explore next?
> Do I have a change to get the 1. version approved by the svn community?
> Do I have a change to get the 2. version approved by the serf
> community? :)
I guess that you realise by now that there's a large overlap between the
two. :)
I just read through RFC 7235 and the way I read this, It's perfectly OK
and blessed from on high to use status 401 to require a multi-factor
token. The interaction would look like this:
1. Client: sends request to URL
2. Server: responds with 401 + WWW-Authenticate for initial
username+password authentication, with Subversion's realm=... parameter
3. Client: sends to URL + Authorization with username and password
(This is how it works now, regardless of authentication type, and
the client continues to send further requests with the same
Authorization header. In the multi-factor scenario, what happens
next is; I'll illustrate with TOTP):
4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based PIN)
6. Server: processes the request and responds with a generated token in
a header (or cookies). The token could be a JWT if we want more
control or a random token as suggested by Greg.
7. Client sends "Authorization: Bearer <token>" with further requests.
This works for other 2FA schemes, too; for example, in step 4 the server
could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==,
realm=..." and in step 5 the client would respond with "Authenticate:
SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to
generate the token.
This does not require any changes in Serf and is, as far as I can see,
compliant with RFC 7235. But you do need an authentication handler on
the server side to handle the second (and third and fourth... there's no
reason this would be limited to two factors). Also if you use some
random token, the authn handler has to store it and eventually
invalidate it; a JWT contains its expiration time, removing the need for
a token database on the server, but it's a bit of a pain to implement.
On the Subversion client side, libsvn_ra_serf might have to grow another
hook for multi-factor callbacks, and we'd need another authentication
provider that would store the shared-secret per realm, similar to what
the username provider does now.
>
> Best regards,
> Peter
>
> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>
>>>> Hi,
>>>>
>>>> So basically the patch becomes this
>>>> I can't say I like the actual branch condition, but I'm open to
>>>> suggestions :)
>>>>
>>> Hi,
>>>
>>> I have not studied the patches in detail but I'm not so sure if I
>>> like the
>>> idea of Serf special-casing / hardcoding a custom response reason. I
>>> feel
>>> it would be better to offloading this to Subversion since we control
>>> both
>>> ends there.
>>
>>
>> I agree. Serf is a general-purpose HTTP client, what we're talking
>> about here is application-level behaviour. Serf already offloads
>> authentication to the application, I also can't see a reason why this
>> would be special-cased in Serf.
>>
>>> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
>>> header
>>> - I don't know if it would be possible to use this to send the
>>> challenge.
>>
>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>> the client /how/ to authenticate, it's there also support complex
>> authentication processes.
>>
>>> The response could then be added as a header field. Would it be
>>> possible
>>> for the server to return a bearer token (= more or less the same as a
>>> Set-Cookie) that we could store client-side to include on future
>>> requests?
>>
>> I'm surprised that multi-step challenge/response mechanism isn't
>> already standardised in HTTP. True, all the multi-factor schemes I've
>> used to date are for authentication flow in browsers, where the
>> server presents a user interface. For headless cases, things like API
>> tokens tend to be generated in advance through an out of band channel
>> (again, usually through a UI in a browser). App tokens are, again,
>> not multi-factor authentication.
>>
>> Maybe we will have to invent an HTTP workflow for this, but let's not
>> go it alone. This is, after all, the ASF and there are a few people
>> around that are ... quite knowledgeable about HTTP. I suggest we
>> consult. Worst case, there may be an IETF RFC waiting to be written.
>>
>> -- Brane
>>
>>
>> P.S.: I say "worst case" because it should've been written long ago
>> instead of people using status 499 and stuff like that.
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 23. 5. 25 23:48, Peter Balogh wrote:
> Hi,
>
> The reason I choose the 499 status code, that it was the cleanest way
> to reroute the 2FA case in auth.c dispatch_auth function
> Hard-coding the 401 can also accomplish this
> But without that, I have two directions I can take, and I'd appreciate
> some insight, what should I try next:
>
> 1.
> I can provide a response with 401 status and valid WWW-Authenticate
> header where I control the realm string
> I can use that to intercept the 2FA request in
> svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the
> 2FA input
> That combined with bearer token, that we return could work without
> modifying serf
>
> 2.
> I can introduce a new serf__authn_scheme_t, and have a cleaner
> implementation, but it means serf would have an unofficial auth scheme
> implementation
>
> I'm all for doing the right thing, working out how to extend the RFC,
> but I have 0 knowledge or experience doing that
> I'm happy to help any way I can, but I'd rather not wait for months,
> before implementing this :)
>
> What do you think, what route should I explore next?
> Do I have a change to get the 1. version approved by the svn community?
> Do I have a change to get the 2. version approved by the serf
> community? :)
I guess that you realise by now that there's a large overlap between the
two. :)
I just read through RFC 7235 and the way I read this, It's perfectly OK
and blessed from on high to use status 401 to require a multi-factor
token. The interaction would look like this:
1. Client: sends request to URL
2. Server: responds with 401 + WWW-Authenticate for initial
username+password authentication, with Subversion's realm=... parameter
3. Client: sends to URL + Authorization with username and password
(This is how it works now, regardless of authentication type, and
the client continues to send further requests with the same
Authorization header. In the multi-factor scenario, what happens
next is; I'll illustrate with TOTP):
4. Server responds with 401 + "WWW-Authenticate: TOTP realm=..."
5. Client: sends to URL + "Authorization: TOTP 123456" (the time-based PIN)
6. Server: processes the request and responds with a generated token in
a header (or cookies). The token could be a JWT if we want more
control or a random token as suggested by Greg.
7. Client sends "Authorization: Bearer <token>" with further requests.
This works for other 2FA schemes, too; for example, in step 4 the server
could respond with "WWW-Authenticate: SCRAM challenge=Y2hhbGxlbmdlPw==,
realm=..." and in step 5 the client would respond with "Authenticate:
SCRAM cmVzcG9uc2Uh", using the shared secret and the challenge to
generate the token.
This does not require any changes in Serf and is, as far as I can see,
compliant with RFC 7235. But you do need an authentication handler on
the server side to handle the second (and third and fourth... there's no
reason this would be limited to two factors). Also if you use some
random token, the authn handler has to store it and eventually
invalidate it; a JWT contains its expiration time, removing the need for
a token database on the server, but it's a bit of a pain to implement.
On the Subversion client side, libsvn_ra_serf might have to grow another
hook for multi-factor callbacks, and we'd need another authentication
provider that would store the shared-secret per realm, similar to what
the username provider does now.
>
> Best regards,
> Peter
>
> On 2025. 05. 23. 17:28, Branko Čibej wrote:
>> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>>
>>>> Hi,
>>>>
>>>> So basically the patch becomes this
>>>> I can't say I like the actual branch condition, but I'm open to
>>>> suggestions :)
>>>>
>>> Hi,
>>>
>>> I have not studied the patches in detail but I'm not so sure if I
>>> like the
>>> idea of Serf special-casing / hardcoding a custom response reason. I
>>> feel
>>> it would be better to offloading this to Subversion since we control
>>> both
>>> ends there.
>>
>>
>> I agree. Serf is a general-purpose HTTP client, what we're talking
>> about here is application-level behaviour. Serf already offloads
>> authentication to the application, I also can't see a reason why this
>> would be special-cased in Serf.
>>
>>> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
>>> header
>>> - I don't know if it would be possible to use this to send the
>>> challenge.
>>
>> I have to read up on WWW-Authenticate. ISTR that aside from telling
>> the client /how/ to authenticate, it's there also support complex
>> authentication processes.
>>
>>> The response could then be added as a header field. Would it be
>>> possible
>>> for the server to return a bearer token (= more or less the same as a
>>> Set-Cookie) that we could store client-side to include on future
>>> requests?
>>
>> I'm surprised that multi-step challenge/response mechanism isn't
>> already standardised in HTTP. True, all the multi-factor schemes I've
>> used to date are for authentication flow in browsers, where the
>> server presents a user interface. For headless cases, things like API
>> tokens tend to be generated in advance through an out of band channel
>> (again, usually through a UI in a browser). App tokens are, again,
>> not multi-factor authentication.
>>
>> Maybe we will have to invent an HTTP workflow for this, but let's not
>> go it alone. This is, after all, the ASF and there are a few people
>> around that are ... quite knowledgeable about HTTP. I suggest we
>> consult. Worst case, there may be an IETF RFC waiting to be written.
>>
>> -- Brane
>>
>>
>> P.S.: I say "worst case" because it should've been written long ago
>> instead of people using status 499 and stuff like that.
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
The reason I choose the 499 status code, that it was the cleanest way to
reroute the 2FA case in auth.c dispatch_auth function
Hard-coding the 401 can also accomplish this
But without that, I have two directions I can take, and I'd appreciate
some insight, what should I try next:
1.
I can provide a response with 401 status and valid WWW-Authenticate
header where I control the realm string
I can use that to intercept the 2FA request in
svn_ra_serf__credentials_callback in libsvn_ra_serf util.c, and do the
2FA input
That combined with bearer token, that we return could work without
modifying serf
2.
I can introduce a new serf__authn_scheme_t, and have a cleaner
implementation, but it means serf would have an unofficial auth scheme
implementation
I'm all for doing the right thing, working out how to extend the RFC,
but I have 0 knowledge or experience doing that
I'm happy to help any way I can, but I'd rather not wait for months,
before implementing this :)
What do you think, what route should I explore next?
Do I have a change to get the 1. version approved by the svn community?
Do I have a change to get the 2. version approved by the serf community? :)
Best regards,
Peter
On 2025. 05. 23. 17:28, Branko Čibej wrote:
> On 23. 5. 25 17:05, Daniel Sahlberg wrote:
>> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>>
>>> Hi,
>>>
>>> So basically the patch becomes this
>>> I can't say I like the actual branch condition, but I'm open to
>>> suggestions :)
>>>
>> Hi,
>>
>> I have not studied the patches in detail but I'm not so sure if I
>> like the
>> idea of Serf special-casing / hardcoding a custom response reason. I
>> feel
>> it would be better to offloading this to Subversion since we control
>> both
>> ends there.
>
>
> I agree. Serf is a general-purpose HTTP client, what we're talking
> about here is application-level behaviour. Serf already offloads
> authentication to the application, I also can't see a reason why this
> would be special-cased in Serf.
>
>> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate
>> header
>> - I don't know if it would be possible to use this to send the
>> challenge.
>
> I have to read up on WWW-Authenticate. ISTR that aside from telling
> the client /how/ to authenticate, it's there also support complex
> authentication processes.
>
>> The response could then be added as a header field. Would it be possible
>> for the server to return a bearer token (= more or less the same as a
>> Set-Cookie) that we could store client-side to include on future
>> requests?
>
> I'm surprised that multi-step challenge/response mechanism isn't
> already standardised in HTTP. True, all the multi-factor schemes I've
> used to date are for authentication flow in browsers, where the server
> presents a user interface. For headless cases, things like API tokens
> tend to be generated in advance through an out of band channel (again,
> usually through a UI in a browser). App tokens are, again, not
> multi-factor authentication.
>
> Maybe we will have to invent an HTTP workflow for this, but let's not
> go it alone. This is, after all, the ASF and there are a few people
> around that are ... quite knowledgeable about HTTP. I suggest we
> consult. Worst case, there may be an IETF RFC waiting to be written.
>
> -- Brane
>
>
> P.S.: I say "worst case" because it should've been written long ago
> instead of people using status 499 and stuff like that.
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 23. 5. 25 17:05, Daniel Sahlberg wrote:
> Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh<pe...@svnplus.com>:
>
>> Hi,
>>
>> So basically the patch becomes this
>> I can't say I like the actual branch condition, but I'm open to
>> suggestions :)
>>
> Hi,
>
> I have not studied the patches in detail but I'm not so sure if I like the
> idea of Serf special-casing / hardcoding a custom response reason. I feel
> it would be better to offloading this to Subversion since we control both
> ends there.
I agree. Serf is a general-purpose HTTP client, what we're talking about
here is application-level behaviour. Serf already offloads
authentication to the application, I also can't see a reason why this
would be special-cased in Serf.
> Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header
> - I don't know if it would be possible to use this to send the challenge.
I have to read up on WWW-Authenticate. ISTR that aside from telling the
client /how/ to authenticate, it's there also support complex
authentication processes.
> The response could then be added as a header field. Would it be possible
> for the server to return a bearer token (= more or less the same as a
> Set-Cookie) that we could store client-side to include on future requests?
I'm surprised that multi-step challenge/response mechanism isn't already
standardised in HTTP. True, all the multi-factor schemes I've used to
date are for authentication flow in browsers, where the server presents
a user interface. For headless cases, things like API tokens tend to be
generated in advance through an out of band channel (again, usually
through a UI in a browser). App tokens are, again, not multi-factor
authentication.
Maybe we will have to invent an HTTP workflow for this, but let's not go
it alone. This is, after all, the ASF and there are a few people around
that are ... quite knowledgeable about HTTP. I suggest we consult. Worst
case, there may be an IETF RFC waiting to be written.
-- Brane
P.S.: I say "worst case" because it should've been written long ago
instead of people using status 499 and stuff like that.
Re: 2FA prototype
Posted by Daniel Sahlberg <da...@gmail.com>.
Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh <pe...@svnplus.com>:
> Hi,
>
> So basically the patch becomes this
> I can't say I like the actual branch condition, but I'm open to
> suggestions :)
>
Hi,
I have not studied the patches in detail but I'm not so sure if I like the
idea of Serf special-casing / hardcoding a custom response reason. I feel
it would be better to offloading this to Subversion since we control both
ends there.
Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header
- I don't know if it would be possible to use this to send the challenge.
The response could then be added as a header field. Would it be possible
for the server to return a bearer token (= more or less the same as a
Set-Cookie) that we could store client-side to include on future requests?
Kind regards,
Daniel Sahlberg
[1] https://www.rfc-editor.org/rfc/rfc7235#section-3.1
>
> Best regards,
> Peter
>
> On 2025. 05. 21. 23:47, Peter Balogh wrote:
> > Hi,
> >
> > Would my approach (especially the serf change) acceptable, if instead
> > of 499, I rely on the 401 reason string from the status line?
> >
> > Best regards,
> > Peter
> >
> > On 2025. 05. 19. 12:37, Greg Stein wrote:
> >> Hi Peter,
> >>
> >> Apologies for not seeing this on the Subversion dev@ list when you
> >> first brought it up.
> >>
> >> Generally speaking, 2FA solutions along this set of requirements, use
> >> a "Bearer token" which is then placed into the Authorization: header.
> >> (sometimes referred to as a Personal Access Token (PAT)). That token
> >> is fetched out of band, placed into a config file, and then picked up
> >> for authentication with the origin server. I've seen this pattern
> >> used across many systems, and I would not like to see a custom 499
> >> HTTP response to (re)invent the wheel. Nor cookies. Just place the
> >> token into the Authorization header.
> >>
> >> I believe there are four parts here:
> >> 1. a cgi that gets placed on an svn server that can generate a bearer
> >> token for an authenticated user (standard HTTP Basic/Digest,
> >> according to whatever ACLs the server may want to use for access to
> >> that cgi). The bearer token is placed into a sqlite database on the
> >> svn server.
> >> 2. the user provides the bearer token to the svn client, which is
> >> saved into a new auth scheme in the svn config directories.
> >> "svn.bearer", for example.
> >> 3. a serf authentication API/mechanism to submit a Bearer token, and
> >> svn will present the bearer token extracted from its config
> >> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> >> could also bet you that such exists, so the above parts could be
> >> edited to match
> >>
> >> For the token used in this system, I would suggest Python's
> >> "secrets.token_hex(20)" to generate a hex string of 40
> >> characters, which represents 160 bits for a token (which I believe
> >> should be sufficient for this system; I'd think the CGI could simply
> >> have a constant that local installations may want to edit).
> >>
> >> Cheers,
> >> -g
> >>
> >> ps. for step 1, I imagine that the Apache Infra team would like to
> >> implement a custom solution to generate the bearer token for its
> >> deployment on ASF systems, but a CGI is a great mechanism for all
> >> third parties and to demonstrate the minimum needs to construct such
> >> tokens.
> >>
> >>
> >> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
> >>
> >> Hi,
> >>
> >> I'm moving this conversation from the subversion dev mailing list
> >> for now
> >> I'm working on adding 2FA to subversion
> >>
> >> I have a working PoC of this system, and I'd like to start
> >> submitting patches.
> >> The serf changes are attached, what is the process to get approval
> >> for this?
> >>
> >> The patches, configs and scripts to make this work are publicly
> >> available here:
> >> https://pub.svnplus.com/repo/2fa/trunk
> >>
> >> The implementation uses a special 499 http response code to
> >> request 2FA auth, I have a working server config that serves this
> >> without any server side changes
> >> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
> >>
> >> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> >> and it works in the browser and the svn cli with the patches
> >> applied, but the svn client does not yet save the cookie, so every
> >> command needs a 2fa
> >>
> >> To access the demo system, use the username: user and password: pass
> >> The 2FA QR code is displayed on the page
> >>
> >> Please let me know, what you think
> >>
> >> Best regards,
> >> Peter
> >>
> >> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
> >>> Hi,
> >>>
> >>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh
> >>> <pe...@svnplus.com>:
> >>>
> >>> Hi,
> >>>
> >>> I'm working on a proof of concept to add multi factor
> >>> authentication to
> >>> subversion
> >>> I have multiple directions, and I'd like to get some feedback
> >>> from this
> >>> group before I head down the wrong road
> >>> Please let me know, if I should read up on any of these, I
> >>> did not find
> >>> any recent conversation about these topics
> >>>
> >>>
> >>> I think this is a very interesting concept!
> >>>
> >>>
> >>> 1. One option would be to extend the existing Basic auth with
> >>> another
> >>> challenge. This would support standard TOTP without external
> >>> connections
> >>> I couldn't find any standard way to communicating this
> >>> through HTTP, my
> >>> best solution would be to
> >>>
> >>> 1.A extend the 401 response with information that the system
> >>> also needs
> >>> a TOTP token
> >>> I've only found the realm string I can use for this without
> >>> modifying
> >>> the serf library
> >>>
> >>> 1.B reject the username + password attempt with a different 401
> >>> This would have to be handled inside the serf library
> >>>
> >>>
> >>> I don't see a problem modifying Serf if it is needed. Several of
> >>> the Subversion committers are also Serf committers and we can
> >>> help there.
> >>>
> >>>
> >>> 2. Provide an external login path instead Basic auth. This
> >>> would open up
> >>> using oauth or similar external providers, but a web based
> >>> provider
> >>> could be run besides svn as well
> >>> The server would respond with a 30X response, and the cmdline
> >>> could
> >>> print the url for the user to open, login and return to the
> >>> terminal
> >>> after authentication
> >>> This would feel less native, but pretty common these days
> >>>
> >>>
> >>> I like this idea - I guess this would open up to for example
> >>> Microsoft Entra.
> >>>
> >>> Make sure to use the standard baton/callback method to
> >>> communicate the redirect URL to the client. This way GUI clients
> >>> (for example TortoiseSVN) can implement a more "native" solution
> >>> to the redirect.
> >>>
> >>>
> >>> All of the solutions above would result in a HTTP cookie that
> >>> would be
> >>> stored encrypted in the auth folder, and sent with every
> >>> subsequent request
> >>>
> >>>
> >>> See existing discussions about storing the basic auth password in
> >>> the auth folder. On Windows, there are APIs to encrypt the
> >>> password linked to the user profile. In general no such on Unix,
> >>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
> >>>
> >>>
> >>> Do you have any thoughts or preferences about this?
> >>> Do you see any technical or security issue with these?
> >>>
> >>>
> >>> I know very little about the technical details of authentication
> >>> on the http level but I think it would be god to adhere to
> >>> existing standards as much as possible instead of inventing
> >>> something unique to Subversion. For example it would be good if
> >>> this can be done across a forward/reverse proxy.
> >>>
> >>> If this feature is enabled on a server, it would be impossible to
> >>> authenticate with an older client. Don't know if this is a
> >>> compatibility concern or not, but I think this addition would
> >>> warrant new releases.
> >>>
> >>> Kind regards,
> >>> Daniel
> >>>
Re: 2FA prototype
Posted by Daniel Sahlberg <da...@gmail.com>.
Den fre 23 maj 2025 kl 00:35 skrev Peter Balogh <pe...@svnplus.com>:
> Hi,
>
> So basically the patch becomes this
> I can't say I like the actual branch condition, but I'm open to
> suggestions :)
>
Hi,
I have not studied the patches in detail but I'm not so sure if I like the
idea of Serf special-casing / hardcoding a custom response reason. I feel
it would be better to offloading this to Subversion since we control both
ends there.
Also, RFC7235 [1] require a 401 response to send a WWW-Authenticate header
- I don't know if it would be possible to use this to send the challenge.
The response could then be added as a header field. Would it be possible
for the server to return a bearer token (= more or less the same as a
Set-Cookie) that we could store client-side to include on future requests?
Kind regards,
Daniel Sahlberg
[1] https://www.rfc-editor.org/rfc/rfc7235#section-3.1
>
> Best regards,
> Peter
>
> On 2025. 05. 21. 23:47, Peter Balogh wrote:
> > Hi,
> >
> > Would my approach (especially the serf change) acceptable, if instead
> > of 499, I rely on the 401 reason string from the status line?
> >
> > Best regards,
> > Peter
> >
> > On 2025. 05. 19. 12:37, Greg Stein wrote:
> >> Hi Peter,
> >>
> >> Apologies for not seeing this on the Subversion dev@ list when you
> >> first brought it up.
> >>
> >> Generally speaking, 2FA solutions along this set of requirements, use
> >> a "Bearer token" which is then placed into the Authorization: header.
> >> (sometimes referred to as a Personal Access Token (PAT)). That token
> >> is fetched out of band, placed into a config file, and then picked up
> >> for authentication with the origin server. I've seen this pattern
> >> used across many systems, and I would not like to see a custom 499
> >> HTTP response to (re)invent the wheel. Nor cookies. Just place the
> >> token into the Authorization header.
> >>
> >> I believe there are four parts here:
> >> 1. a cgi that gets placed on an svn server that can generate a bearer
> >> token for an authenticated user (standard HTTP Basic/Digest,
> >> according to whatever ACLs the server may want to use for access to
> >> that cgi). The bearer token is placed into a sqlite database on the
> >> svn server.
> >> 2. the user provides the bearer token to the svn client, which is
> >> saved into a new auth scheme in the svn config directories.
> >> "svn.bearer", for example.
> >> 3. a serf authentication API/mechanism to submit a Bearer token, and
> >> svn will present the bearer token extracted from its config
> >> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> >> could also bet you that such exists, so the above parts could be
> >> edited to match
> >>
> >> For the token used in this system, I would suggest Python's
> >> "secrets.token_hex(20)" to generate a hex string of 40
> >> characters, which represents 160 bits for a token (which I believe
> >> should be sufficient for this system; I'd think the CGI could simply
> >> have a constant that local installations may want to edit).
> >>
> >> Cheers,
> >> -g
> >>
> >> ps. for step 1, I imagine that the Apache Infra team would like to
> >> implement a custom solution to generate the bearer token for its
> >> deployment on ASF systems, but a CGI is a great mechanism for all
> >> third parties and to demonstrate the minimum needs to construct such
> >> tokens.
> >>
> >>
> >> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
> >>
> >> Hi,
> >>
> >> I'm moving this conversation from the subversion dev mailing list
> >> for now
> >> I'm working on adding 2FA to subversion
> >>
> >> I have a working PoC of this system, and I'd like to start
> >> submitting patches.
> >> The serf changes are attached, what is the process to get approval
> >> for this?
> >>
> >> The patches, configs and scripts to make this work are publicly
> >> available here:
> >> https://pub.svnplus.com/repo/2fa/trunk
> >>
> >> The implementation uses a special 499 http response code to
> >> request 2FA auth, I have a working server config that serves this
> >> without any server side changes
> >> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
> >>
> >> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> >> and it works in the browser and the svn cli with the patches
> >> applied, but the svn client does not yet save the cookie, so every
> >> command needs a 2fa
> >>
> >> To access the demo system, use the username: user and password: pass
> >> The 2FA QR code is displayed on the page
> >>
> >> Please let me know, what you think
> >>
> >> Best regards,
> >> Peter
> >>
> >> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
> >>> Hi,
> >>>
> >>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh
> >>> <pe...@svnplus.com>:
> >>>
> >>> Hi,
> >>>
> >>> I'm working on a proof of concept to add multi factor
> >>> authentication to
> >>> subversion
> >>> I have multiple directions, and I'd like to get some feedback
> >>> from this
> >>> group before I head down the wrong road
> >>> Please let me know, if I should read up on any of these, I
> >>> did not find
> >>> any recent conversation about these topics
> >>>
> >>>
> >>> I think this is a very interesting concept!
> >>>
> >>>
> >>> 1. One option would be to extend the existing Basic auth with
> >>> another
> >>> challenge. This would support standard TOTP without external
> >>> connections
> >>> I couldn't find any standard way to communicating this
> >>> through HTTP, my
> >>> best solution would be to
> >>>
> >>> 1.A extend the 401 response with information that the system
> >>> also needs
> >>> a TOTP token
> >>> I've only found the realm string I can use for this without
> >>> modifying
> >>> the serf library
> >>>
> >>> 1.B reject the username + password attempt with a different 401
> >>> This would have to be handled inside the serf library
> >>>
> >>>
> >>> I don't see a problem modifying Serf if it is needed. Several of
> >>> the Subversion committers are also Serf committers and we can
> >>> help there.
> >>>
> >>>
> >>> 2. Provide an external login path instead Basic auth. This
> >>> would open up
> >>> using oauth or similar external providers, but a web based
> >>> provider
> >>> could be run besides svn as well
> >>> The server would respond with a 30X response, and the cmdline
> >>> could
> >>> print the url for the user to open, login and return to the
> >>> terminal
> >>> after authentication
> >>> This would feel less native, but pretty common these days
> >>>
> >>>
> >>> I like this idea - I guess this would open up to for example
> >>> Microsoft Entra.
> >>>
> >>> Make sure to use the standard baton/callback method to
> >>> communicate the redirect URL to the client. This way GUI clients
> >>> (for example TortoiseSVN) can implement a more "native" solution
> >>> to the redirect.
> >>>
> >>>
> >>> All of the solutions above would result in a HTTP cookie that
> >>> would be
> >>> stored encrypted in the auth folder, and sent with every
> >>> subsequent request
> >>>
> >>>
> >>> See existing discussions about storing the basic auth password in
> >>> the auth folder. On Windows, there are APIs to encrypt the
> >>> password linked to the user profile. In general no such on Unix,
> >>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
> >>>
> >>>
> >>> Do you have any thoughts or preferences about this?
> >>> Do you see any technical or security issue with these?
> >>>
> >>>
> >>> I know very little about the technical details of authentication
> >>> on the http level but I think it would be god to adhere to
> >>> existing standards as much as possible instead of inventing
> >>> something unique to Subversion. For example it would be good if
> >>> this can be done across a forward/reverse proxy.
> >>>
> >>> If this feature is enabled on a server, it would be impossible to
> >>> authenticate with an older client. Don't know if this is a
> >>> compatibility concern or not, but I think this addition would
> >>> warrant new releases.
> >>>
> >>> Kind regards,
> >>> Daniel
> >>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
So basically the patch becomes this
I can't say I like the actual branch condition, but I'm open to
suggestions :)
Best regards,
Peter
On 2025. 05. 21. 23:47, Peter Balogh wrote:
> Hi,
>
> Would my approach (especially the serf change) acceptable, if instead
> of 499, I rely on the 401 reason string from the status line?
>
> Best regards,
> Peter
>
> On 2025. 05. 19. 12:37, Greg Stein wrote:
>> Hi Peter,
>>
>> Apologies for not seeing this on the Subversion dev@ list when you
>> first brought it up.
>>
>> Generally speaking, 2FA solutions along this set of requirements, use
>> a "Bearer token" which is then placed into the Authorization: header.
>> (sometimes referred to as a Personal Access Token (PAT)). That token
>> is fetched out of band, placed into a config file, and then picked up
>> for authentication with the origin server. I've seen this pattern
>> used across many systems, and I would not like to see a custom 499
>> HTTP response to (re)invent the wheel. Nor cookies. Just place the
>> token into the Authorization header.
>>
>> I believe there are four parts here:
>> 1. a cgi that gets placed on an svn server that can generate a bearer
>> token for an authenticated user (standard HTTP Basic/Digest,
>> according to whatever ACLs the server may want to use for access to
>> that cgi). The bearer token is placed into a sqlite database on the
>> svn server.
>> 2. the user provides the bearer token to the svn client, which is
>> saved into a new auth scheme in the svn config directories.
>> "svn.bearer", for example.
>> 3. a serf authentication API/mechanism to submit a Bearer token, and
>> svn will present the bearer token extracted from its config
>> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
>> could also bet you that such exists, so the above parts could be
>> edited to match
>>
>> For the token used in this system, I would suggest Python's
>> "secrets.token_hex(20)" to generate a hex string of 40
>> characters, which represents 160 bits for a token (which I believe
>> should be sufficient for this system; I'd think the CGI could simply
>> have a constant that local installations may want to edit).
>>
>> Cheers,
>> -g
>>
>> ps. for step 1, I imagine that the Apache Infra team would like to
>> implement a custom solution to generate the bearer token for its
>> deployment on ASF systems, but a CGI is a great mechanism for all
>> third parties and to demonstrate the minimum needs to construct such
>> tokens.
>>
>>
>> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>>
>> Hi,
>>
>> I'm moving this conversation from the subversion dev mailing list
>> for now
>> I'm working on adding 2FA to subversion
>>
>> I have a working PoC of this system, and I'd like to start
>> submitting patches.
>> The serf changes are attached, what is the process to get approval
>> for this?
>>
>> The patches, configs and scripts to make this work are publicly
>> available here:
>> https://pub.svnplus.com/repo/2fa/trunk
>>
>> The implementation uses a special 499 http response code to
>> request 2FA auth, I have a working server config that serves this
>> without any server side changes
>> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>>
>> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
>> and it works in the browser and the svn cli with the patches
>> applied, but the svn client does not yet save the cookie, so every
>> command needs a 2fa
>>
>> To access the demo system, use the username: user and password: pass
>> The 2FA QR code is displayed on the page
>>
>> Please let me know, what you think
>>
>> Best regards,
>> Peter
>>
>> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>>> Hi,
>>>
>>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh
>>> <pe...@svnplus.com>:
>>>
>>> Hi,
>>>
>>> I'm working on a proof of concept to add multi factor
>>> authentication to
>>> subversion
>>> I have multiple directions, and I'd like to get some feedback
>>> from this
>>> group before I head down the wrong road
>>> Please let me know, if I should read up on any of these, I
>>> did not find
>>> any recent conversation about these topics
>>>
>>>
>>> I think this is a very interesting concept!
>>>
>>>
>>> 1. One option would be to extend the existing Basic auth with
>>> another
>>> challenge. This would support standard TOTP without external
>>> connections
>>> I couldn't find any standard way to communicating this
>>> through HTTP, my
>>> best solution would be to
>>>
>>> 1.A extend the 401 response with information that the system
>>> also needs
>>> a TOTP token
>>> I've only found the realm string I can use for this without
>>> modifying
>>> the serf library
>>>
>>> 1.B reject the username + password attempt with a different 401
>>> This would have to be handled inside the serf library
>>>
>>>
>>> I don't see a problem modifying Serf if it is needed. Several of
>>> the Subversion committers are also Serf committers and we can
>>> help there.
>>>
>>>
>>> 2. Provide an external login path instead Basic auth. This
>>> would open up
>>> using oauth or similar external providers, but a web based
>>> provider
>>> could be run besides svn as well
>>> The server would respond with a 30X response, and the cmdline
>>> could
>>> print the url for the user to open, login and return to the
>>> terminal
>>> after authentication
>>> This would feel less native, but pretty common these days
>>>
>>>
>>> I like this idea - I guess this would open up to for example
>>> Microsoft Entra.
>>>
>>> Make sure to use the standard baton/callback method to
>>> communicate the redirect URL to the client. This way GUI clients
>>> (for example TortoiseSVN) can implement a more "native" solution
>>> to the redirect.
>>>
>>>
>>> All of the solutions above would result in a HTTP cookie that
>>> would be
>>> stored encrypted in the auth folder, and sent with every
>>> subsequent request
>>>
>>>
>>> See existing discussions about storing the basic auth password in
>>> the auth folder. On Windows, there are APIs to encrypt the
>>> password linked to the user profile. In general no such on Unix,
>>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>>
>>>
>>> Do you have any thoughts or preferences about this?
>>> Do you see any technical or security issue with these?
>>>
>>>
>>> I know very little about the technical details of authentication
>>> on the http level but I think it would be god to adhere to
>>> existing standards as much as possible instead of inventing
>>> something unique to Subversion. For example it would be good if
>>> this can be done across a forward/reverse proxy.
>>>
>>> If this feature is enabled on a server, it would be impossible to
>>> authenticate with an older client. Don't know if this is a
>>> compatibility concern or not, but I think this addition would
>>> warrant new releases.
>>>
>>> Kind regards,
>>> Daniel
>>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
So basically the patch becomes this
I can't say I like the actual branch condition, but I'm open to
suggestions :)
Best regards,
Peter
On 2025. 05. 21. 23:47, Peter Balogh wrote:
> Hi,
>
> Would my approach (especially the serf change) acceptable, if instead
> of 499, I rely on the 401 reason string from the status line?
>
> Best regards,
> Peter
>
> On 2025. 05. 19. 12:37, Greg Stein wrote:
>> Hi Peter,
>>
>> Apologies for not seeing this on the Subversion dev@ list when you
>> first brought it up.
>>
>> Generally speaking, 2FA solutions along this set of requirements, use
>> a "Bearer token" which is then placed into the Authorization: header.
>> (sometimes referred to as a Personal Access Token (PAT)). That token
>> is fetched out of band, placed into a config file, and then picked up
>> for authentication with the origin server. I've seen this pattern
>> used across many systems, and I would not like to see a custom 499
>> HTTP response to (re)invent the wheel. Nor cookies. Just place the
>> token into the Authorization header.
>>
>> I believe there are four parts here:
>> 1. a cgi that gets placed on an svn server that can generate a bearer
>> token for an authenticated user (standard HTTP Basic/Digest,
>> according to whatever ACLs the server may want to use for access to
>> that cgi). The bearer token is placed into a sqlite database on the
>> svn server.
>> 2. the user provides the bearer token to the svn client, which is
>> saved into a new auth scheme in the svn config directories.
>> "svn.bearer", for example.
>> 3. a serf authentication API/mechanism to submit a Bearer token, and
>> svn will present the bearer token extracted from its config
>> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
>> could also bet you that such exists, so the above parts could be
>> edited to match
>>
>> For the token used in this system, I would suggest Python's
>> "secrets.token_hex(20)" to generate a hex string of 40
>> characters, which represents 160 bits for a token (which I believe
>> should be sufficient for this system; I'd think the CGI could simply
>> have a constant that local installations may want to edit).
>>
>> Cheers,
>> -g
>>
>> ps. for step 1, I imagine that the Apache Infra team would like to
>> implement a custom solution to generate the bearer token for its
>> deployment on ASF systems, but a CGI is a great mechanism for all
>> third parties and to demonstrate the minimum needs to construct such
>> tokens.
>>
>>
>> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>>
>> Hi,
>>
>> I'm moving this conversation from the subversion dev mailing list
>> for now
>> I'm working on adding 2FA to subversion
>>
>> I have a working PoC of this system, and I'd like to start
>> submitting patches.
>> The serf changes are attached, what is the process to get approval
>> for this?
>>
>> The patches, configs and scripts to make this work are publicly
>> available here:
>> https://pub.svnplus.com/repo/2fa/trunk
>>
>> The implementation uses a special 499 http response code to
>> request 2FA auth, I have a working server config that serves this
>> without any server side changes
>> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>>
>> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
>> and it works in the browser and the svn cli with the patches
>> applied, but the svn client does not yet save the cookie, so every
>> command needs a 2fa
>>
>> To access the demo system, use the username: user and password: pass
>> The 2FA QR code is displayed on the page
>>
>> Please let me know, what you think
>>
>> Best regards,
>> Peter
>>
>> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>>> Hi,
>>>
>>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh
>>> <pe...@svnplus.com>:
>>>
>>> Hi,
>>>
>>> I'm working on a proof of concept to add multi factor
>>> authentication to
>>> subversion
>>> I have multiple directions, and I'd like to get some feedback
>>> from this
>>> group before I head down the wrong road
>>> Please let me know, if I should read up on any of these, I
>>> did not find
>>> any recent conversation about these topics
>>>
>>>
>>> I think this is a very interesting concept!
>>>
>>>
>>> 1. One option would be to extend the existing Basic auth with
>>> another
>>> challenge. This would support standard TOTP without external
>>> connections
>>> I couldn't find any standard way to communicating this
>>> through HTTP, my
>>> best solution would be to
>>>
>>> 1.A extend the 401 response with information that the system
>>> also needs
>>> a TOTP token
>>> I've only found the realm string I can use for this without
>>> modifying
>>> the serf library
>>>
>>> 1.B reject the username + password attempt with a different 401
>>> This would have to be handled inside the serf library
>>>
>>>
>>> I don't see a problem modifying Serf if it is needed. Several of
>>> the Subversion committers are also Serf committers and we can
>>> help there.
>>>
>>>
>>> 2. Provide an external login path instead Basic auth. This
>>> would open up
>>> using oauth or similar external providers, but a web based
>>> provider
>>> could be run besides svn as well
>>> The server would respond with a 30X response, and the cmdline
>>> could
>>> print the url for the user to open, login and return to the
>>> terminal
>>> after authentication
>>> This would feel less native, but pretty common these days
>>>
>>>
>>> I like this idea - I guess this would open up to for example
>>> Microsoft Entra.
>>>
>>> Make sure to use the standard baton/callback method to
>>> communicate the redirect URL to the client. This way GUI clients
>>> (for example TortoiseSVN) can implement a more "native" solution
>>> to the redirect.
>>>
>>>
>>> All of the solutions above would result in a HTTP cookie that
>>> would be
>>> stored encrypted in the auth folder, and sent with every
>>> subsequent request
>>>
>>>
>>> See existing discussions about storing the basic auth password in
>>> the auth folder. On Windows, there are APIs to encrypt the
>>> password linked to the user profile. In general no such on Unix,
>>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>>
>>>
>>> Do you have any thoughts or preferences about this?
>>> Do you see any technical or security issue with these?
>>>
>>>
>>> I know very little about the technical details of authentication
>>> on the http level but I think it would be god to adhere to
>>> existing standards as much as possible instead of inventing
>>> something unique to Subversion. For example it would be good if
>>> this can be done across a forward/reverse proxy.
>>>
>>> If this feature is enabled on a server, it would be impossible to
>>> authenticate with an older client. Don't know if this is a
>>> compatibility concern or not, but I think this addition would
>>> warrant new releases.
>>>
>>> Kind regards,
>>> Daniel
>>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Would my approach (especially the serf change) acceptable, if instead of
499, I rely on the 401 reason string from the status line?
Best regards,
Peter
On 2025. 05. 19. 12:37, Greg Stein wrote:
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you
> first brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use
> a "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token
> is fetched out of band, placed into a config file, and then picked up
> for authentication with the origin server. I've seen this pattern used
> across many systems, and I would not like to see a custom 499 HTTP
> response to (re)invent the wheel. Nor cookies. Just place the token
> into the Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according
> to whatever ACLs the server may want to use for access to that cgi).
> The bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is
> saved into a new auth scheme in the svn config directories.
> "svn.bearer", for example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and
> svn will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> could also bet you that such exists, so the above parts could be
> edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40
> characters, which represents 160 bits for a token (which I believe
> should be sufficient for this system; I'd think the CGI could simply
> have a constant that local installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its
> deployment on ASF systems, but a CGI is a great mechanism for all
> third parties and to demonstrate the minimum needs to construct such
> tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list
> for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start
> submitting patches.
> The serf changes are attached, what is the process to get approval
> for this?
>
> The patches, configs and scripts to make this work are publicly
> available here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to
> request 2FA auth, I have a working server config that serves this
> without any server side changes
> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> and it works in the browser and the svn cli with the patches
> applied, but the svn client does not yet save the cookie, so every
> command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor
>> authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback
>> from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I
>> did not find
>> any recent conversation about these topics
>>
>>
>> I think this is a very interesting concept!
>>
>>
>> 1. One option would be to extend the existing Basic auth with
>> another
>> challenge. This would support standard TOTP without external
>> connections
>> I couldn't find any standard way to communicating this
>> through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system
>> also needs
>> a TOTP token
>> I've only found the realm string I can use for this without
>> modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of
>> the Subversion committers are also Serf committers and we can
>> help there.
>>
>>
>> 2. Provide an external login path instead Basic auth. This
>> would open up
>> using oauth or similar external providers, but a web based
>> provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline
>> could
>> print the url for the user to open, login and return to the
>> terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>>
>> I like this idea - I guess this would open up to for example
>> Microsoft Entra.
>>
>> Make sure to use the standard baton/callback method to
>> communicate the redirect URL to the client. This way GUI clients
>> (for example TortoiseSVN) can implement a more "native" solution
>> to the redirect.
>>
>>
>> All of the solutions above would result in a HTTP cookie that
>> would be
>> stored encrypted in the auth folder, and sent with every
>> subsequent request
>>
>>
>> See existing discussions about storing the basic auth password in
>> the auth folder. On Windows, there are APIs to encrypt the
>> password linked to the user profile. In general no such on Unix,
>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>>
>> I know very little about the technical details of authentication
>> on the http level but I think it would be god to adhere to
>> existing standards as much as possible instead of inventing
>> something unique to Subversion. For example it would be good if
>> this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a
>> compatibility concern or not, but I think this addition would
>> warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 19. 5. 25 19:28, Greg Stein wrote:
> For svn+ssh, since we control both ends of that conversation, it would
> be possible to add an additional challenge/response for a 2FA (TOTP?)
> mechanism. I find this rather dubious, however, as SSH access already
> implies a very intimate level of access and may already have some
> level of 2FA incorporated (eg. ASF Infra has 2FA applied to some SSH
> access).
Just an aside: that's probably done with the pam_otp plugin, SSH knows
how to wrap itself around that.
-- Brane
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 19. 5. 25 19:33, Greg Stein wrote:
> [clarifying]
>
> On Mon, May 19, 2025 at 12:28 PM Greg Stein <gs...@gmail.com> wrote:
>
> Using an OAuth-based workflow that incorporates 2FA. That is
> already possible.
>
>
> I've already seen this done.
>
> What is *really* hard is to incorporate 2FA into the svn
> client/libraries. The most straightforward is to use bearer/PAT
> tokens, as it requires client changes.
>
>
> Mixed this up. Hard to incorporate since 2FA requires client changes.
> ... Given current APIs within svn, I believe the most straightforward
> is bearer/PAT tokens.
>
> And some (likely) minimal changes to the Serf API. Per above message,
> ignore svn+ssh.
Probably no changes in Serf; it can be implemented directly at the RA
layer (plus callback) on our side and an authn handler on the httpd
side, all you really need is an extra HTTP req/rsp for the OTP
handshake. Would work with bearer tokens, too, it's just a lot more
complicated to implement, having more moving parts.
If it were me, I'd start with TOTP (RFC 6238), because it doesn't have
to involve a third party beyond the client and the server and it's a
known thing with multiple useful client-side implementations, from
various authenticator apps and password managers to totp-cli for the
command line and no doubt several libraries. Or we could roll our own,
it's not that hard. I'd be absolutely stunned if the HTTPd-side
integration for that doesn't already exist, probably in 79.3 different
versions (63 working and some twice that between 1% and 50% done, is
where the 16.3 comes from...).
-- Brane
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 19. 5. 25 21:30, Branko Čibej wrote:
> On 19. 5. 25 20:26, Peter Balogh wrote:
>>
>> Hi,
>>
>> So an OAuth based 2FA auth flow would result in a cookie in the browser
>> Why don't we extend SVN to handle the same flow?
>>
>
> No technical reason except that no-one sane wants to implement a real
> HTTP browser in Subversion, with cookies and all that entails.
>
>
>> Can you please explain, in your view, how is a session id that we
>> communicate via Cookie headers different from a Bearer token?
>
> A bearer token is just a specific HTTP request header. We can handle
> those. So are cookies, really, but Subversion is (see above) not a
> generic browser. It's bad enough that OAuth2 essentially _requires_
> that the authentication happens in a browser. So headless tools like
> svn usually offload that to whatever the users current default browser
> happens to be ... it's a huge mess to make that work on multiple
> platforms. I really don't think any of us has the time (or desire) to
> go there.
>
>
>> As far as I know (I don't have any RFC past besides my google foo)
>> there's no standard way of authenticating with username + password + totp
>
> I'd be surprised if there isn't. The trick with appending ";<totp
> token>" to the password sure works with HTTP basic auth. I haven't
> looked at the code of mod-authn-otp to see what it actually does,
> other than it supports basic and digest authentication.
So it turns out that _this_ module requires *only* the one-time
password, not the "real" user's password. Which is basically fine, since
the shared secret for generating one-time PINs works just like a password.
This isn't the same as 2FA, though, it's a single factor; sorry. So, I
suppose we'd have to find another solution.
-- Brane
Re: 2FA prototype
Posted by Branko Čibej <br...@apache.org>.
On 19. 5. 25 20:26, Peter Balogh wrote:
>
> Hi,
>
> So an OAuth based 2FA auth flow would result in a cookie in the browser
> Why don't we extend SVN to handle the same flow?
>
No technical reason except that no-one sane wants to implement a real
HTTP browser in Subversion, with cookies and all that entails.
> Can you please explain, in your view, how is a session id that we
> communicate via Cookie headers different from a Bearer token?
A bearer token is just a specific HTTP request header. We can handle
those. So are cookies, really, but Subversion is (see above) not a
generic browser. It's bad enough that OAuth2 essentially _requires_ that
the authentication happens in a browser. So headless tools like svn
usually offload that to whatever the users current default browser
happens to be ... it's a huge mess to make that work on multiple
platforms. I really don't think any of us has the time (or desire) to go
there.
> As far as I know (I don't have any RFC past besides my google foo)
> there's no standard way of authenticating with username + password + totp
I'd be surprised if there isn't. The trick with appending ";<totp
token>" to the password sure works with HTTP basic auth. I haven't
looked at the code of mod-authn-otp to see what it actually does, other
than it supports basic and digest authentication.
Oh yes, here: https://github.com/archiecobbs/mod-authn-otp
Note that this ^^^ is not something Subversion would ever support, we'd
only implement the client side of that protocol.
-- Brane
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
So an OAuth based 2FA auth flow would result in a cookie in the browser
Why don't we extend SVN to handle the same flow?
Can you please explain, in your view, how is a session id that we
communicate via Cookie headers different from a Bearer token?
As far as I know (I don't have any RFC past besides my google foo)
there's no standard way of authenticating with username + password + totp
So why not follow the next best thing, a public easy to edit website
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes that lists 499
as Token Required? :)
My goal was to have a system, that requires no server binary
modification, and adds security on top of the current solutions, while
not sacrificing usability or loosing svn cli, tvsn or browser based access
I don't see how a Bearer token based solution would be better, and how a
Cookie based system with HTTP 499 would be worse
I'm happy to change course, and implement what makes most sense for the
project on the client side, but I'd rather not get into trying to drive
an apache change through the linux deployment pipelines, I have no
experience with that, but I expect that to take years
If we go down the OAuth pass, do you envision the cli client to allow
login without a browser? Is there a protocol, example system that can do
that?
What server response would trigger an oauth flow in the svn client?
Best regards,
Peter
On 2025. 05. 19. 19:33, Greg Stein wrote:
> [clarifying]
>
> On Mon, May 19, 2025 at 12:28 PM Greg Stein <gs...@gmail.com> wrote:
>
> Using an OAuth-based workflow that incorporates 2FA. That is
> already possible.
>
>
> I've already seen this done.
>
> What is *really* hard is to incorporate 2FA into the svn
> client/libraries. The most straightforward is to use bearer/PAT
> tokens, as it requires client changes.
>
>
> Mixed this up. Hard to incorporate since 2FA requires client changes.
> ... Given current APIs within svn, I believe the most straightforward
> is bearer/PAT tokens.
>
> And some (likely) minimal changes to the Serf API. Per above message,
> ignore svn+ssh.
>
> >...
>
> Cheers,
> -g
>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
So an OAuth based 2FA auth flow would result in a cookie in the browser
Why don't we extend SVN to handle the same flow?
Can you please explain, in your view, how is a session id that we
communicate via Cookie headers different from a Bearer token?
As far as I know (I don't have any RFC past besides my google foo)
there's no standard way of authenticating with username + password + totp
So why not follow the next best thing, a public easy to edit website
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes that lists 499
as Token Required? :)
My goal was to have a system, that requires no server binary
modification, and adds security on top of the current solutions, while
not sacrificing usability or loosing svn cli, tvsn or browser based access
I don't see how a Bearer token based solution would be better, and how a
Cookie based system with HTTP 499 would be worse
I'm happy to change course, and implement what makes most sense for the
project on the client side, but I'd rather not get into trying to drive
an apache change through the linux deployment pipelines, I have no
experience with that, but I expect that to take years
If we go down the OAuth pass, do you envision the cli client to allow
login without a browser? Is there a protocol, example system that can do
that?
What server response would trigger an oauth flow in the svn client?
Best regards,
Peter
On 2025. 05. 19. 19:33, Greg Stein wrote:
> [clarifying]
>
> On Mon, May 19, 2025 at 12:28 PM Greg Stein <gs...@gmail.com> wrote:
>
> Using an OAuth-based workflow that incorporates 2FA. That is
> already possible.
>
>
> I've already seen this done.
>
> What is *really* hard is to incorporate 2FA into the svn
> client/libraries. The most straightforward is to use bearer/PAT
> tokens, as it requires client changes.
>
>
> Mixed this up. Hard to incorporate since 2FA requires client changes.
> ... Given current APIs within svn, I believe the most straightforward
> is bearer/PAT tokens.
>
> And some (likely) minimal changes to the Serf API. Per above message,
> ignore svn+ssh.
>
> >...
>
> Cheers,
> -g
>
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
[clarifying]
On Mon, May 19, 2025 at 12:28 PM Greg Stein <gs...@gmail.com> wrote:
> Using an OAuth-based workflow that incorporates 2FA. That is already
> possible.
>
I've already seen this done.
> What is *really* hard is to incorporate 2FA into the svn client/libraries.
> The most straightforward is to use bearer/PAT tokens, as it requires client
> changes.
>
Mixed this up. Hard to incorporate since 2FA requires client changes. ...
Given current APIs within svn, I believe the most straightforward is
bearer/PAT tokens.
And some (likely) minimal changes to the Serf API. Per above message,
ignore svn+ssh.
>...
Cheers,
-g
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
[clarifying]
On Mon, May 19, 2025 at 12:28 PM Greg Stein <gs...@gmail.com> wrote:
> Using an OAuth-based workflow that incorporates 2FA. That is already
> possible.
>
I've already seen this done.
> What is *really* hard is to incorporate 2FA into the svn client/libraries.
> The most straightforward is to use bearer/PAT tokens, as it requires client
> changes.
>
Mixed this up. Hard to incorporate since 2FA requires client changes. ...
Given current APIs within svn, I believe the most straightforward is
bearer/PAT tokens.
And some (likely) minimal changes to the Serf API. Per above message,
ignore svn+ssh.
>...
Cheers,
-g
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
Using an OAuth-based workflow that incorporates 2FA. That is already
possible.
What is *really* hard is to incorporate 2FA into the svn client/libraries.
The most straightforward is to use bearer/PAT tokens, as it requires client
changes. It might be possible to construct an svn client auth provider that
uses TOTP. However, there is no standardized HTTP protocol that I'm aware
of which says "I accept your user/pass, now provide the correct TOTP code".
(happy to be educated; my RFC learning is about 10 years old)
For svn+ssh, since we control both ends of that conversation, it would be
possible to add an additional challenge/response for a 2FA (TOTP?)
mechanism. I find this rather dubious, however, as SSH access already
implies a very intimate level of access and may already have some level of
2FA incorporated (eg. ASF Infra has 2FA applied to some SSH access).
Cheers,
-g
On Mon, May 19, 2025 at 6:26 AM Peter Balogh <pe...@svnplus.com> wrote:
> Hi,
>
> Thanks, in this case, how would you authenticate using a browser?
>
> Best regards,
> Peter
>
> On 2025. 05. 19. 12:37, Greg Stein wrote:
>
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you first
> brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use a
> "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token is
> fetched out of band, placed into a config file, and then picked up for
> authentication with the origin server. I've seen this pattern used across
> many systems, and I would not like to see a custom 499 HTTP response to
> (re)invent the wheel. Nor cookies. Just place the token into the
> Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according to
> whatever ACLs the server may want to use for access to that cgi). The
> bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is saved
> into a new auth scheme in the svn config directories. "svn.bearer", for
> example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and svn
> will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I could
> also bet you that such exists, so the above parts could be edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40 characters, which
> represents 160 bits for a token (which I believe should be sufficient for
> this system; I'd think the CGI could simply have a constant that local
> installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its deployment
> on ASF systems, but a CGI is a great mechanism for all third parties and to
> demonstrate the minimum needs to construct such tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
>> Hi,
>>
>> I'm moving this conversation from the subversion dev mailing list for now
>> I'm working on adding 2FA to subversion
>>
>> I have a working PoC of this system, and I'd like to start submitting
>> patches.
>> The serf changes are attached, what is the process to get approval for
>> this?
>>
>> The patches, configs and scripts to make this work are publicly available
>> here:
>> https://pub.svnplus.com/repo/2fa/trunk
>>
>> The implementation uses a special 499 http response code to request 2FA
>> auth, I have a working server config that serves this without any server
>> side changes https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>>
>> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/, and it
>> works in the browser and the svn cli with the patches applied, but the svn
>> client does not yet save the cookie, so every command needs a 2fa
>>
>> To access the demo system, use the username: user and password: pass
>> The 2FA QR code is displayed on the page
>>
>> Please let me know, what you think
>>
>> Best regards,
>> Peter
>>
>> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>>
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>>> Hi,
>>>
>>> I'm working on a proof of concept to add multi factor authentication to
>>> subversion
>>> I have multiple directions, and I'd like to get some feedback from this
>>> group before I head down the wrong road
>>> Please let me know, if I should read up on any of these, I did not find
>>> any recent conversation about these topics
>>>
>>
>> I think this is a very interesting concept!
>>
>>
>>>
>>> 1. One option would be to extend the existing Basic auth with another
>>> challenge. This would support standard TOTP without external connections
>>> I couldn't find any standard way to communicating this through HTTP, my
>>> best solution would be to
>>>
>>> 1.A extend the 401 response with information that the system also needs
>>> a TOTP token
>>> I've only found the realm string I can use for this without modifying
>>> the serf library
>>>
>>> 1.B reject the username + password attempt with a different 401
>>> This would have to be handled inside the serf library
>>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of the
>> Subversion committers are also Serf committers and we can help there.
>>
>>
>>>
>>> 2. Provide an external login path instead Basic auth. This would open up
>>> using oauth or similar external providers, but a web based provider
>>> could be run besides svn as well
>>> The server would respond with a 30X response, and the cmdline could
>>> print the url for the user to open, login and return to the terminal
>>> after authentication
>>> This would feel less native, but pretty common these days
>>>
>>
>> I like this idea - I guess this would open up to for example Microsoft
>> Entra.
>>
>> Make sure to use the standard baton/callback method to communicate the
>> redirect URL to the client. This way GUI clients (for example TortoiseSVN)
>> can implement a more "native" solution to the redirect.
>>
>>
>>>
>>> All of the solutions above would result in a HTTP cookie that would be
>>> stored encrypted in the auth folder, and sent with every subsequent
>>> request
>>>
>>
>> See existing discussions about storing the basic auth password in the
>> auth folder. On Windows, there are APIs to encrypt the password linked to
>> the user profile. In general no such on Unix, but I assume it could be
>> stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>>>
>>> Do you have any thoughts or preferences about this?
>>> Do you see any technical or security issue with these?
>>>
>>
>> I know very little about the technical details of authentication on the
>> http level but I think it would be god to adhere to existing standards as
>> much as possible instead of inventing something unique to Subversion. For
>> example it would be good if this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a compatibility
>> concern or not, but I think this addition would warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
>>
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
Using an OAuth-based workflow that incorporates 2FA. That is already
possible.
What is *really* hard is to incorporate 2FA into the svn client/libraries.
The most straightforward is to use bearer/PAT tokens, as it requires client
changes. It might be possible to construct an svn client auth provider that
uses TOTP. However, there is no standardized HTTP protocol that I'm aware
of which says "I accept your user/pass, now provide the correct TOTP code".
(happy to be educated; my RFC learning is about 10 years old)
For svn+ssh, since we control both ends of that conversation, it would be
possible to add an additional challenge/response for a 2FA (TOTP?)
mechanism. I find this rather dubious, however, as SSH access already
implies a very intimate level of access and may already have some level of
2FA incorporated (eg. ASF Infra has 2FA applied to some SSH access).
Cheers,
-g
On Mon, May 19, 2025 at 6:26 AM Peter Balogh <pe...@svnplus.com> wrote:
> Hi,
>
> Thanks, in this case, how would you authenticate using a browser?
>
> Best regards,
> Peter
>
> On 2025. 05. 19. 12:37, Greg Stein wrote:
>
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you first
> brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use a
> "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token is
> fetched out of band, placed into a config file, and then picked up for
> authentication with the origin server. I've seen this pattern used across
> many systems, and I would not like to see a custom 499 HTTP response to
> (re)invent the wheel. Nor cookies. Just place the token into the
> Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according to
> whatever ACLs the server may want to use for access to that cgi). The
> bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is saved
> into a new auth scheme in the svn config directories. "svn.bearer", for
> example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and svn
> will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I could
> also bet you that such exists, so the above parts could be edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40 characters, which
> represents 160 bits for a token (which I believe should be sufficient for
> this system; I'd think the CGI could simply have a constant that local
> installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its deployment
> on ASF systems, but a CGI is a great mechanism for all third parties and to
> demonstrate the minimum needs to construct such tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
>> Hi,
>>
>> I'm moving this conversation from the subversion dev mailing list for now
>> I'm working on adding 2FA to subversion
>>
>> I have a working PoC of this system, and I'd like to start submitting
>> patches.
>> The serf changes are attached, what is the process to get approval for
>> this?
>>
>> The patches, configs and scripts to make this work are publicly available
>> here:
>> https://pub.svnplus.com/repo/2fa/trunk
>>
>> The implementation uses a special 499 http response code to request 2FA
>> auth, I have a working server config that serves this without any server
>> side changes https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>>
>> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/, and it
>> works in the browser and the svn cli with the patches applied, but the svn
>> client does not yet save the cookie, so every command needs a 2fa
>>
>> To access the demo system, use the username: user and password: pass
>> The 2FA QR code is displayed on the page
>>
>> Please let me know, what you think
>>
>> Best regards,
>> Peter
>>
>> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>>
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>>> Hi,
>>>
>>> I'm working on a proof of concept to add multi factor authentication to
>>> subversion
>>> I have multiple directions, and I'd like to get some feedback from this
>>> group before I head down the wrong road
>>> Please let me know, if I should read up on any of these, I did not find
>>> any recent conversation about these topics
>>>
>>
>> I think this is a very interesting concept!
>>
>>
>>>
>>> 1. One option would be to extend the existing Basic auth with another
>>> challenge. This would support standard TOTP without external connections
>>> I couldn't find any standard way to communicating this through HTTP, my
>>> best solution would be to
>>>
>>> 1.A extend the 401 response with information that the system also needs
>>> a TOTP token
>>> I've only found the realm string I can use for this without modifying
>>> the serf library
>>>
>>> 1.B reject the username + password attempt with a different 401
>>> This would have to be handled inside the serf library
>>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of the
>> Subversion committers are also Serf committers and we can help there.
>>
>>
>>>
>>> 2. Provide an external login path instead Basic auth. This would open up
>>> using oauth or similar external providers, but a web based provider
>>> could be run besides svn as well
>>> The server would respond with a 30X response, and the cmdline could
>>> print the url for the user to open, login and return to the terminal
>>> after authentication
>>> This would feel less native, but pretty common these days
>>>
>>
>> I like this idea - I guess this would open up to for example Microsoft
>> Entra.
>>
>> Make sure to use the standard baton/callback method to communicate the
>> redirect URL to the client. This way GUI clients (for example TortoiseSVN)
>> can implement a more "native" solution to the redirect.
>>
>>
>>>
>>> All of the solutions above would result in a HTTP cookie that would be
>>> stored encrypted in the auth folder, and sent with every subsequent
>>> request
>>>
>>
>> See existing discussions about storing the basic auth password in the
>> auth folder. On Windows, there are APIs to encrypt the password linked to
>> the user profile. In general no such on Unix, but I assume it could be
>> stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>>>
>>> Do you have any thoughts or preferences about this?
>>> Do you see any technical or security issue with these?
>>>
>>
>> I know very little about the technical details of authentication on the
>> http level but I think it would be god to adhere to existing standards as
>> much as possible instead of inventing something unique to Subversion. For
>> example it would be good if this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a compatibility
>> concern or not, but I think this addition would warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Thanks, in this case, how would you authenticate using a browser?
Best regards,
Peter
On 2025. 05. 19. 12:37, Greg Stein wrote:
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you
> first brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use
> a "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token
> is fetched out of band, placed into a config file, and then picked up
> for authentication with the origin server. I've seen this pattern used
> across many systems, and I would not like to see a custom 499 HTTP
> response to (re)invent the wheel. Nor cookies. Just place the token
> into the Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according
> to whatever ACLs the server may want to use for access to that cgi).
> The bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is
> saved into a new auth scheme in the svn config directories.
> "svn.bearer", for example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and
> svn will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> could also bet you that such exists, so the above parts could be
> edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40
> characters, which represents 160 bits for a token (which I believe
> should be sufficient for this system; I'd think the CGI could simply
> have a constant that local installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its
> deployment on ASF systems, but a CGI is a great mechanism for all
> third parties and to demonstrate the minimum needs to construct such
> tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list
> for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start
> submitting patches.
> The serf changes are attached, what is the process to get approval
> for this?
>
> The patches, configs and scripts to make this work are publicly
> available here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to
> request 2FA auth, I have a working server config that serves this
> without any server side changes
> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> and it works in the browser and the svn cli with the patches
> applied, but the svn client does not yet save the cookie, so every
> command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor
>> authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback
>> from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I
>> did not find
>> any recent conversation about these topics
>>
>>
>> I think this is a very interesting concept!
>>
>>
>> 1. One option would be to extend the existing Basic auth with
>> another
>> challenge. This would support standard TOTP without external
>> connections
>> I couldn't find any standard way to communicating this
>> through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system
>> also needs
>> a TOTP token
>> I've only found the realm string I can use for this without
>> modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of
>> the Subversion committers are also Serf committers and we can
>> help there.
>>
>>
>> 2. Provide an external login path instead Basic auth. This
>> would open up
>> using oauth or similar external providers, but a web based
>> provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline
>> could
>> print the url for the user to open, login and return to the
>> terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>>
>> I like this idea - I guess this would open up to for example
>> Microsoft Entra.
>>
>> Make sure to use the standard baton/callback method to
>> communicate the redirect URL to the client. This way GUI clients
>> (for example TortoiseSVN) can implement a more "native" solution
>> to the redirect.
>>
>>
>> All of the solutions above would result in a HTTP cookie that
>> would be
>> stored encrypted in the auth folder, and sent with every
>> subsequent request
>>
>>
>> See existing discussions about storing the basic auth password in
>> the auth folder. On Windows, there are APIs to encrypt the
>> password linked to the user profile. In general no such on Unix,
>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>>
>> I know very little about the technical details of authentication
>> on the http level but I think it would be god to adhere to
>> existing standards as much as possible instead of inventing
>> something unique to Subversion. For example it would be good if
>> this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a
>> compatibility concern or not, but I think this addition would
>> warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Would my approach (especially the serf change) acceptable, if instead of
499, I rely on the 401 reason string from the status line?
Best regards,
Peter
On 2025. 05. 19. 12:37, Greg Stein wrote:
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you
> first brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use
> a "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token
> is fetched out of band, placed into a config file, and then picked up
> for authentication with the origin server. I've seen this pattern used
> across many systems, and I would not like to see a custom 499 HTTP
> response to (re)invent the wheel. Nor cookies. Just place the token
> into the Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according
> to whatever ACLs the server may want to use for access to that cgi).
> The bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is
> saved into a new auth scheme in the svn config directories.
> "svn.bearer", for example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and
> svn will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> could also bet you that such exists, so the above parts could be
> edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40
> characters, which represents 160 bits for a token (which I believe
> should be sufficient for this system; I'd think the CGI could simply
> have a constant that local installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its
> deployment on ASF systems, but a CGI is a great mechanism for all
> third parties and to demonstrate the minimum needs to construct such
> tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list
> for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start
> submitting patches.
> The serf changes are attached, what is the process to get approval
> for this?
>
> The patches, configs and scripts to make this work are publicly
> available here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to
> request 2FA auth, I have a working server config that serves this
> without any server side changes
> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> and it works in the browser and the svn cli with the patches
> applied, but the svn client does not yet save the cookie, so every
> command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor
>> authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback
>> from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I
>> did not find
>> any recent conversation about these topics
>>
>>
>> I think this is a very interesting concept!
>>
>>
>> 1. One option would be to extend the existing Basic auth with
>> another
>> challenge. This would support standard TOTP without external
>> connections
>> I couldn't find any standard way to communicating this
>> through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system
>> also needs
>> a TOTP token
>> I've only found the realm string I can use for this without
>> modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of
>> the Subversion committers are also Serf committers and we can
>> help there.
>>
>>
>> 2. Provide an external login path instead Basic auth. This
>> would open up
>> using oauth or similar external providers, but a web based
>> provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline
>> could
>> print the url for the user to open, login and return to the
>> terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>>
>> I like this idea - I guess this would open up to for example
>> Microsoft Entra.
>>
>> Make sure to use the standard baton/callback method to
>> communicate the redirect URL to the client. This way GUI clients
>> (for example TortoiseSVN) can implement a more "native" solution
>> to the redirect.
>>
>>
>> All of the solutions above would result in a HTTP cookie that
>> would be
>> stored encrypted in the auth folder, and sent with every
>> subsequent request
>>
>>
>> See existing discussions about storing the basic auth password in
>> the auth folder. On Windows, there are APIs to encrypt the
>> password linked to the user profile. In general no such on Unix,
>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>>
>> I know very little about the technical details of authentication
>> on the http level but I think it would be god to adhere to
>> existing standards as much as possible instead of inventing
>> something unique to Subversion. For example it would be good if
>> this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a
>> compatibility concern or not, but I think this addition would
>> warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
Re: 2FA prototype
Posted by Peter Balogh <pe...@svnplus.com>.
Hi,
Thanks, in this case, how would you authenticate using a browser?
Best regards,
Peter
On 2025. 05. 19. 12:37, Greg Stein wrote:
> Hi Peter,
>
> Apologies for not seeing this on the Subversion dev@ list when you
> first brought it up.
>
> Generally speaking, 2FA solutions along this set of requirements, use
> a "Bearer token" which is then placed into the Authorization: header.
> (sometimes referred to as a Personal Access Token (PAT)). That token
> is fetched out of band, placed into a config file, and then picked up
> for authentication with the origin server. I've seen this pattern used
> across many systems, and I would not like to see a custom 499 HTTP
> response to (re)invent the wheel. Nor cookies. Just place the token
> into the Authorization header.
>
> I believe there are four parts here:
> 1. a cgi that gets placed on an svn server that can generate a bearer
> token for an authenticated user (standard HTTP Basic/Digest, according
> to whatever ACLs the server may want to use for access to that cgi).
> The bearer token is placed into a sqlite database on the svn server.
> 2. the user provides the bearer token to the svn client, which is
> saved into a new auth scheme in the svn config directories.
> "svn.bearer", for example.
> 3. a serf authentication API/mechanism to submit a Bearer token, and
> svn will present the bearer token extracted from its config
> 4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I
> could also bet you that such exists, so the above parts could be
> edited to match
>
> For the token used in this system, I would suggest Python's
> "secrets.token_hex(20)" to generate a hex string of 40
> characters, which represents 160 bits for a token (which I believe
> should be sufficient for this system; I'd think the CGI could simply
> have a constant that local installations may want to edit).
>
> Cheers,
> -g
>
> ps. for step 1, I imagine that the Apache Infra team would like to
> implement a custom solution to generate the bearer token for its
> deployment on ASF systems, but a CGI is a great mechanism for all
> third parties and to demonstrate the minimum needs to construct such
> tokens.
>
>
> On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
>
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list
> for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start
> submitting patches.
> The serf changes are attached, what is the process to get approval
> for this?
>
> The patches, configs and scripts to make this work are publicly
> available here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to
> request 2FA auth, I have a working server config that serves this
> without any server side changes
> https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/,
> and it works in the browser and the svn cli with the patches
> applied, but the svn client does not yet save the cookie, so every
> command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>> Hi,
>>
>> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor
>> authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback
>> from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I
>> did not find
>> any recent conversation about these topics
>>
>>
>> I think this is a very interesting concept!
>>
>>
>> 1. One option would be to extend the existing Basic auth with
>> another
>> challenge. This would support standard TOTP without external
>> connections
>> I couldn't find any standard way to communicating this
>> through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system
>> also needs
>> a TOTP token
>> I've only found the realm string I can use for this without
>> modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>>
>> I don't see a problem modifying Serf if it is needed. Several of
>> the Subversion committers are also Serf committers and we can
>> help there.
>>
>>
>> 2. Provide an external login path instead Basic auth. This
>> would open up
>> using oauth or similar external providers, but a web based
>> provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline
>> could
>> print the url for the user to open, login and return to the
>> terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>>
>> I like this idea - I guess this would open up to for example
>> Microsoft Entra.
>>
>> Make sure to use the standard baton/callback method to
>> communicate the redirect URL to the client. This way GUI clients
>> (for example TortoiseSVN) can implement a more "native" solution
>> to the redirect.
>>
>>
>> All of the solutions above would result in a HTTP cookie that
>> would be
>> stored encrypted in the auth folder, and sent with every
>> subsequent request
>>
>>
>> See existing discussions about storing the basic auth password in
>> the auth folder. On Windows, there are APIs to encrypt the
>> password linked to the user profile. In general no such on Unix,
>> but I assume it could be stored in Gnome Keyring/Kwallet/GPG-agent.
>>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>>
>> I know very little about the technical details of authentication
>> on the http level but I think it would be god to adhere to
>> existing standards as much as possible instead of inventing
>> something unique to Subversion. For example it would be good if
>> this can be done across a forward/reverse proxy.
>>
>> If this feature is enabled on a server, it would be impossible to
>> authenticate with an older client. Don't know if this is a
>> compatibility concern or not, but I think this addition would
>> warrant new releases.
>>
>> Kind regards,
>> Daniel
>>
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
Hi Peter,
Apologies for not seeing this on the Subversion dev@ list when you first
brought it up.
Generally speaking, 2FA solutions along this set of requirements, use a
"Bearer token" which is then placed into the Authorization: header.
(sometimes referred to as a Personal Access Token (PAT)). That token is
fetched out of band, placed into a config file, and then picked up for
authentication with the origin server. I've seen this pattern used across
many systems, and I would not like to see a custom 499 HTTP response to
(re)invent the wheel. Nor cookies. Just place the token into the
Authorization header.
I believe there are four parts here:
1. a cgi that gets placed on an svn server that can generate a bearer token
for an authenticated user (standard HTTP Basic/Digest, according to
whatever ACLs the server may want to use for access to that cgi). The
bearer token is placed into a sqlite database on the svn server.
2. the user provides the bearer token to the svn client, which is saved
into a new auth scheme in the svn config directories. "svn.bearer", for
example.
3. a serf authentication API/mechanism to submit a Bearer token, and svn
will present the bearer token extracted from its config
4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I could
also bet you that such exists, so the above parts could be edited to match
For the token used in this system, I would suggest Python's
"secrets.token_hex(20)" to generate a hex string of 40 characters, which
represents 160 bits for a token (which I believe should be sufficient for
this system; I'd think the CGI could simply have a constant that local
installations may want to edit).
Cheers,
-g
ps. for step 1, I imagine that the Apache Infra team would like to
implement a custom solution to generate the bearer token for its deployment
on ASF systems, but a CGI is a great mechanism for all third parties and to
demonstrate the minimum needs to construct such tokens.
On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start submitting
> patches.
> The serf changes are attached, what is the process to get approval for
> this?
>
> The patches, configs and scripts to make this work are publicly available
> here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to request 2FA
> auth, I have a working server config that serves this without any server
> side changes https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/, and it
> works in the browser and the svn cli with the patches applied, but the svn
> client does not yet save the cookie, so every command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>
> Hi,
>
> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I did not find
>> any recent conversation about these topics
>>
>
> I think this is a very interesting concept!
>
>
>>
>> 1. One option would be to extend the existing Basic auth with another
>> challenge. This would support standard TOTP without external connections
>> I couldn't find any standard way to communicating this through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system also needs
>> a TOTP token
>> I've only found the realm string I can use for this without modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>
> I don't see a problem modifying Serf if it is needed. Several of the
> Subversion committers are also Serf committers and we can help there.
>
>
>>
>> 2. Provide an external login path instead Basic auth. This would open up
>> using oauth or similar external providers, but a web based provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline could
>> print the url for the user to open, login and return to the terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>
> I like this idea - I guess this would open up to for example Microsoft
> Entra.
>
> Make sure to use the standard baton/callback method to communicate the
> redirect URL to the client. This way GUI clients (for example TortoiseSVN)
> can implement a more "native" solution to the redirect.
>
>
>>
>> All of the solutions above would result in a HTTP cookie that would be
>> stored encrypted in the auth folder, and sent with every subsequent
>> request
>>
>
> See existing discussions about storing the basic auth password in the auth
> folder. On Windows, there are APIs to encrypt the password linked to the
> user profile. In general no such on Unix, but I assume it could be stored
> in Gnome Keyring/Kwallet/GPG-agent.
>
>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>
> I know very little about the technical details of authentication on the
> http level but I think it would be god to adhere to existing standards as
> much as possible instead of inventing something unique to Subversion. For
> example it would be good if this can be done across a forward/reverse proxy.
>
> If this feature is enabled on a server, it would be impossible to
> authenticate with an older client. Don't know if this is a compatibility
> concern or not, but I think this addition would warrant new releases.
>
> Kind regards,
> Daniel
>
>
Re: 2FA prototype
Posted by Greg Stein <gs...@gmail.com>.
Hi Peter,
Apologies for not seeing this on the Subversion dev@ list when you first
brought it up.
Generally speaking, 2FA solutions along this set of requirements, use a
"Bearer token" which is then placed into the Authorization: header.
(sometimes referred to as a Personal Access Token (PAT)). That token is
fetched out of band, placed into a config file, and then picked up for
authentication with the origin server. I've seen this pattern used across
many systems, and I would not like to see a custom 499 HTTP response to
(re)invent the wheel. Nor cookies. Just place the token into the
Authorization header.
I believe there are four parts here:
1. a cgi that gets placed on an svn server that can generate a bearer token
for an authenticated user (standard HTTP Basic/Digest, according to
whatever ACLs the server may want to use for access to that cgi). The
bearer token is placed into a sqlite database on the svn server.
2. the user provides the bearer token to the svn client, which is saved
into a new auth scheme in the svn config directories. "svn.bearer", for
example.
3. a serf authentication API/mechanism to submit a Bearer token, and svn
will present the bearer token extracted from its config
4. httpd grows a new "mod_auth_bearer" or "mod_auth_pat" ... and I could
also bet you that such exists, so the above parts could be edited to match
For the token used in this system, I would suggest Python's
"secrets.token_hex(20)" to generate a hex string of 40 characters, which
represents 160 bits for a token (which I believe should be sufficient for
this system; I'd think the CGI could simply have a constant that local
installations may want to edit).
Cheers,
-g
ps. for step 1, I imagine that the Apache Infra team would like to
implement a custom solution to generate the bearer token for its deployment
on ASF systems, but a CGI is a great mechanism for all third parties and to
demonstrate the minimum needs to construct such tokens.
On Sun, May 18, 2025 at 4:18 PM Peter Balogh <pe...@svnplus.com> wrote:
> Hi,
>
> I'm moving this conversation from the subversion dev mailing list for now
> I'm working on adding 2FA to subversion
>
> I have a working PoC of this system, and I'd like to start submitting
> patches.
> The serf changes are attached, what is the process to get approval for
> this?
>
> The patches, configs and scripts to make this work are publicly available
> here:
> https://pub.svnplus.com/repo/2fa/trunk
>
> The implementation uses a special 499 http response code to request 2FA
> auth, I have a working server config that serves this without any server
> side changes https://pub.svnplus.com/repo/2fa/trunk/webdav.conf
>
> The system is running at https://2fa.svnplus.com/repo/2fa/trunk/, and it
> works in the browser and the svn cli with the patches applied, but the svn
> client does not yet save the cookie, so every command needs a 2fa
>
> To access the demo system, use the username: user and password: pass
> The 2FA QR code is displayed on the page
>
> Please let me know, what you think
>
> Best regards,
> Peter
>
> On 2025. 04. 02. 9:25, Daniel Sahlberg wrote:
>
> Hi,
>
> Den mån 31 mars 2025 kl 13:09 skrev Peter Balogh <pe...@svnplus.com>:
>
>> Hi,
>>
>> I'm working on a proof of concept to add multi factor authentication to
>> subversion
>> I have multiple directions, and I'd like to get some feedback from this
>> group before I head down the wrong road
>> Please let me know, if I should read up on any of these, I did not find
>> any recent conversation about these topics
>>
>
> I think this is a very interesting concept!
>
>
>>
>> 1. One option would be to extend the existing Basic auth with another
>> challenge. This would support standard TOTP without external connections
>> I couldn't find any standard way to communicating this through HTTP, my
>> best solution would be to
>>
>> 1.A extend the 401 response with information that the system also needs
>> a TOTP token
>> I've only found the realm string I can use for this without modifying
>> the serf library
>>
>> 1.B reject the username + password attempt with a different 401
>> This would have to be handled inside the serf library
>>
>
> I don't see a problem modifying Serf if it is needed. Several of the
> Subversion committers are also Serf committers and we can help there.
>
>
>>
>> 2. Provide an external login path instead Basic auth. This would open up
>> using oauth or similar external providers, but a web based provider
>> could be run besides svn as well
>> The server would respond with a 30X response, and the cmdline could
>> print the url for the user to open, login and return to the terminal
>> after authentication
>> This would feel less native, but pretty common these days
>>
>
> I like this idea - I guess this would open up to for example Microsoft
> Entra.
>
> Make sure to use the standard baton/callback method to communicate the
> redirect URL to the client. This way GUI clients (for example TortoiseSVN)
> can implement a more "native" solution to the redirect.
>
>
>>
>> All of the solutions above would result in a HTTP cookie that would be
>> stored encrypted in the auth folder, and sent with every subsequent
>> request
>>
>
> See existing discussions about storing the basic auth password in the auth
> folder. On Windows, there are APIs to encrypt the password linked to the
> user profile. In general no such on Unix, but I assume it could be stored
> in Gnome Keyring/Kwallet/GPG-agent.
>
>
>>
>> Do you have any thoughts or preferences about this?
>> Do you see any technical or security issue with these?
>>
>
> I know very little about the technical details of authentication on the
> http level but I think it would be god to adhere to existing standards as
> much as possible instead of inventing something unique to Subversion. For
> example it would be good if this can be done across a forward/reverse proxy.
>
> If this feature is enabled on a server, it would be impossible to
> authenticate with an older client. Don't know if this is a compatibility
> concern or not, but I think this addition would warrant new releases.
>
> Kind regards,
> Daniel
>
>