IWSlackGateway1, Seirdy, IWSlackGateway and gRegor joined the channel
#@lawik↩️ Is there a place you'd recommend covering more of this indieweb stuff? Curious to see what others are doing.
How are people using mf2 and webmention? Particular tools? Roll their own? (twitter.com/_/status/1401038292980744196)
KartikPrabhu joined the channel
#@fluffy↩️ http://indieweb.org is a great place to start, especially the chat! It's a great community and very welcoming. :)
My recommendation if you want to get started is look into mf2 and webmention; those are, IMO, the core of the #indieweb experience. (twitter.com/_/status/1401052088193282051)
#@fluffy↩️ Also for me, the main reason to do mf2 is so that your outgoing webmentions get parsed correctly by peoples' receivers. There's other good reasons to do it as well (like it gives more support for social readers) but that's the big one. (twitter.com/_/status/1401052454821580800)
hendursa1, gRegor, KartikPrabhu and barnaby joined the channel
#barnabyaaronpk et al: I’m working on my indieauth authorization endpoint code, and am wondering about potential account discovery attacks
#barnabyif an endpoint supports multiple accounts, and the me parameter of the request to the authorization endpoint isn’t one of them, what should it do?
#barnabyreturning an error would allow attackers to discover whether a particular user has an account at or is supported by that service
#barnabyand I’m wondering if this is a big deal or not
#barnabyit’s complicated slightly by the fact that I’m considering offering multuple authentication methods, potentially customisable per user, a la indielogin.com
#barnabyso if I want to mitigate account discovery attacks, I’d need to always show all of them
#sknebelif I want to check if a URL can be used to log in with indieauth, I can just fetch the page and check if it declares an endpoint
#sknebelnow a thing you can log into should IMHO go through the login flow and reject a user it doesn't recognize only after they completed the flow
#aaronpkThe "me" is really a hint not a requirement especially since the user might enter something that isn't their canonical URL
#barnabyhmm okay, so a multi-user auth endpoint would always have to display a username field along with whatever auth method is being used (e.g. password, one-time email code, GPG signing a challenge)
#barnabyand assume that anyone who wants to support multiple users is going to have specific enough requirements that they’ll write their own indieauth implementation
gRegor joined the channel
#aaronpkI think there are some low level aspects of IndieAuth that could be done with a library to help people build multi user endpoints
#barnabywell I had a pretty good plan for how to do it, for single-user endpoints!
#barnabybut I’m definitely not yet familiar enough with how multi-user endpoints should work to make it work for them
#barnabyso I’m trying to figure out how I can structure the single-user implementation in a way which will make it easy to add multi-user support later, without over-complicating the single-user use-case
#barnabyeh I’ll just make a single-user version for the moment and worry about multi-user later
#ZegnatWould be interesting to document the big differences you are running into between single- and multi-user. E.g. when I am thinking of using a WordPress site as my IndieAuth provider, I do not see any big difference. Either I am already logged in to the WP Admin and I can approve the auth request, or I am not yet logged in to the WP Admin and WP will ask me to login as any of the many potential admin accounts it knows about. There is no
#Zegnat difference there between single- and multi-user?
#barnabythere’s a difference in the login UX, and therefore customisable authentication backends
#barnabywith single user, you can have a single password field, or send an email with a one-time code to a known email-address, or have a textarea with a challenge for them to GPG sign
#barnabywith multi-user, you need to additionally have a username field, and be able to tell which authentication methods are available/valid for each user
KartikPrabhu joined the channel
#Zegnatyeah, I was just sort of wondering outloud it you even want to see that login UX as part of the IndieAuth flow itself, or make that out of scope and to be handled by surrounding application logic (ie. in the WP example, the WP Admin)
#barnabywell I want people (such as myself) to be able to take the library, plug it into their app with a few lines of code and maybe a configuration file, and have it immediately function as an auth endpoint
#barnabye.g. my site doesn’t have its own auth system, it just uses indieauth
#barnabyany opinions about storing authorization request parameters in redirect URLs rather than session/cookies?
#barnabye.g. if an indieauth client sends an authorization request, and the user isn’t currently logged into their server (e.g. via a cookie), then they’d be redirected to their login page with a redirect URL back to the authorization endpoint, complete with all the original IA authorization request parameters
#barnabythat way, the indieauth parts could be stateless
#barnaby(and therefore way easier to implement and test)
[kimberlyhirsh] joined the channel
#barnabywhatever authentication gets redirected to could in theory change the contents of the redirect URL, and therefore the authorization parameters
#barnabyI suppose there’s a phishing danger, as the authenticating app could change the redirect URL
#barnabyI suppose another method would be to encrypt the parameters with a local secret
#barnabyit’s more work, but still less stateful than cookies or session storage
#ZegnatYeah, that is more what I was thinking of when I was writing before. That I do not think you should put the actual login part of the auth into a module that handles indieauth specific things.
#ZegnatPutting state in the URL is fine in a lot of cases, it is what the state parameter is for in OAuth/IndieAuth :) But you would probably want to sketch it out just to make sure someone cannot use it to trick you into sending out an approve
barnaby joined the channel
#barnabyZegnat: yeah, your example of wanting to redirect to e.g. wordpress auth as part of the process helped clarify how I should be handling thing
#barnabynow I’ve come up with a design which I think will let me do either or, depending on how the library consumer configures it
#barnabyand I think that if an authorisation endpoint which my IA code redirects to is insecure or malicious, then that particular user has bigger problems than that endpoint being able to access some IA requiest parameters
#barnabybecause it can obviously control where it redirects to anyway
#barnabycool, so I can write an entirely stateless library! that makes things vastly simpler
#ZegnatI think the bigger trick is for your authorisation endpoint to know whether the current browser is already logged in or not. If you can solve that, it is a matter of "if not logged in, go to X first and come back once logged in"
#ZegnatAlso if you can do that, you do not really need to handle any other state questions. Nothing needs to specifically be passed around. Once login has happened, the login flow can send the user back to the original URL for the IndieAuth flow without needing to send any other information
#ZegnatIn a PSR-7 based workflow, I would almost expect some middleware to have already checked if a user is logged in or not, but I have not worked with Silex a lot and not sure if there are any examples to go on there.
#barnabywell Silex is abandoned now, that’s one of the reasons I’m writing a framework-independent library
#barnabyback when I wrote the current taproot/authentication, basing it on the Symfony HTTP and routing classes was the closest I could get
#barnabybut since then, PSR-7 showed up, so I can make something which is much more broadly compatible
#ZegnatWhat I have usually seen is that there is an auth middleware (PSR-15) in the chain that checks if the current request is made by a logged in user. And then the user’s data is added as an attribute on the PSR-7 request before it is passed down. One example I could quickly get a result for through Google: https://docs.mezzio.dev/mezzio-authentication/v1/intro/
#barnabyyeah, I’ve seen some similar things. dealing with that is outside the scope of my library code though, and is rather something for consuming code to check
#barnabyas AFAIK there’s no standardised way of getting user data from a request
#ZegnatI was thinking the IndieAuth server part could check an attribute on the request object. Have the user of your lib specify the attribute when your lib is instantiated.
#Zegnat(Note that I am biased on PSR-7 as a comaintainer on a PSR-7 lib with a fair amount of downloads.)
#barnabymy plan is to just have the consuming code define something like an isRequestAuthenticated function, which my library code calls with the request object
#barnabythat way they can use whatever method they want to determine whether the request is authenticated
#ZegnatOn a very high level, I would expect the IndieAuith server to be a PSR-15 request handler. So you would have $iaserver->handle($request). And when I create $iaserver I would have passed in an attribute name like "isAuthenticated". Then when the IndieAuth server is handling a ServerRequest it can do $req->getAttribute($this->attributeName) to figure out what the application has set as the current state
#ZegnatRequest handler. The IndieAuth server would be in charge of giving HTTP responses, right?
#barnabysome of the functions I expose will be very similar to the Request Handler interface, but I’m not sure it’s a great fit for what I have in mind
#ZegnatBut there would be a middleware up the chain that actually checks whether the current browser is logged in or not. And the way that middleware functions (it might highjack and send the user to a login form of some kind) is out-of-scope for the IndieAuth server
#barnabyI need to look into it in more detail. I’m not a huge fan of how the Request Handler interface seems to be based around having one class per route
#barnabybut that’s based on my very cursory knowledge of it
#barnabye.g. my micropub adapter class exposes functions for handling two different routes, the micropub endpoint and the media endpoint
#barnabyso on the surface it looks like a good candidate for being a PSR-15 request handler, but I don’t think it’s such a good fit
#ZegnatPSR-15 does not really care about the amount of routes handled by it. That is up to a router to figure out.
#ZegnatThat repo is now slightly out of date, but was used as an example of how there is no need for a fixed framework when you can string together PSR implementations. See things that are used to turn it into its own site engine in the README: https://github.com/Zegnat/php-website-starter#current-practices
#Loqi[Zegnat] php-website-starter: My minimum viable setup for starting a PHP project.
#ZegnatI really need to update it, Zend Emitter doesn’t even exist anymore. The rename to Laminas has been a while ago now, haha
#barnabyyeah, I see how that can work, but I don’t want to bundle a router with my micropub adapter library. I’d much rather expose a couple of functions which take a request and return a response, and let the consumer fit them into whatever routing they’re using
#barnabyI think the Request Handler interface might be a good fit for parts of my IA library, not sure yet though
#barnabyhmm I suppose one big benefit of bundling your own router inside a Request Handler for an entire pluggable app would be that URL generation is much easier, and encapsulated inside each handler
#barnabythat’d definitely be an argument for that approach if you have something with a lot of routes, which needs to be able to generate URLs for its own routes
hendursaga and jeremycherfas joined the channel
#barnabydo we have stats anywhere on IA code_verifier support?
#barnabyhmm I found another argument for deprecating the old IA flow of redeeming an auth code for a profile at the authorization_endpoint, rather than the token_endpoint
#barnabyit would mean that server implementations can broadly apply CSRF protection to the authorization endpoint, where it’s important, and leave it off the token endpoint, where it shouldn’t be used
#barnabyand having a single route which may or may not require csrf protection can be tricky to configure in some frameworks, e.g. Django, where CSRF protection is applied by default but can be opted out of on a route-by-route basis
[fluffy] joined the channel
#barnabyAre there any guidelines for when IA access tokens should expire, or whether they should expire at all?
jamietanna joined the channel
#jamietannawe're still fleshing that out - and not many folks have expiry - but I've recently moved to 7 day expiring tokens, with refresh tokens as an ability to have effectively limitless access
#Loqijamietanna: barnaby left you a message 1 day, 23 hours ago: thanks for letting me know about the mf ruby CLI! good to know
#Zegnatbarnaby: my tokens also expire after 7 days. Though I have no refresh tokens implemented. I think GWG was also looking into making tokens issued by WordPress expire
#barnabyokay, cool, looks like 7 days is a sane default value then, especially if/when I implement refresh tokens
#barnabyis currently deep in making stateless CSRF protection, hoping to get back to actual indieauth implementation soon
#sknebelit makes sense to have an option to change the expiry in the flow though
#sknebele.g. when you want to give a PESOS service, phone app, ... a long-running token
#barnabyyeah, definitely. but that implies a whole load of extra token management and querying capabilities which are out of the scope of the library I’m making
#barnabyso I’m just making sure that there’s room for consumers to add that functionality themselves if they want
#barnabywhile providing quick and easy sane defaults
#barnabyalthough wouldn’t refresh tokens remove the need for user-configurable expiry times?
#barnabyseems like an additional confusing UX burden
#sknebelrefresh tokens are somewhat orthagonal to "is this connection supposed to be forever"
#barnabyI don’t think I’ve ever seen an OAuth UI which allowed me to configure the token expiry time
#sknebelI'd argue for a default of an infinitely valid token (or token + refresh tokens) *if* you have UI to review and revoke tokens
#aaronpkusually that decision is made by the oauth provider, but there are plenty of examples of UIs for configuring that in the provider side
#GWGI support the functionality for expiring tokens, just no UI or such. So, I would need to just add a setting for what the default expiry was and it would just work
#GWGI thought about adding refresh tokens after jamietanna did it
#GWGBut would likely just add UI on the authorize screen