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 > >