#social 2017-07-15
2017-07-15 UTC
# saranix anyone know why https://w3c-dvcg.github.io/ld-signatures/ is blank?
# ben_thatmustbeme Isn't for me
# saranix hmm.. I see stuff in view source, but firefox does not want to render it.
# ben_thatmustbeme Huh, strange, FF mobile it loads but the is doesn't, so it has no menus or anything
# ben_thatmustbeme Something crazy with it, that's for sure
# ben_thatmustbeme it is, but odd how poorly respec is behaving
timbl, prtksxna and prtksxn__ joined the channel
# saranix hmm looks like https://github.com/w3c/activitypub/blob/gh-pages/implementation-reports/TEMPLATE.md has the same mistake of trailing fragment in Accept: text (profile="https://www.w3.org/ns/activitystreams#")
# xmpp-social [ajordan] aaronpk: even Respec documents show basic content though, without the JS having to work
# saranix !tell puckipedia how far along is Kroeg?
prtksxna and prtksxna_ joined the channel
xmpp-social and prtksxna joined the channel
# ajordan ping sandro, rhiaro again - https://www.w3.org/2017/07/12-social-minutes.html from the CG meeting are still missing :)
# ajordan laughed out loud at https://chat.indieweb.org/social/2017-07-12#t1499876541287000 (side note it's 1 AM atm sooooo...)
# Loqi [aaronpk] too late, just did https://github.com/tootsuite/mastodon/issues/4173
prtksxna and timbl joined the channel
# puckipedia saranix: sooooo. afaik, it's ticking all the boxes?
# puckipedia except for a few security considerations
# puckipedia yep :P
# puckipedia it's 11:55 AM here
# puckipedia CEST
# puckipedia (GMT+2 iirc)
# puckipedia ooh, I just realised an interesting possible security-issue I need to double-check
# puckipedia
{type: Note, to: [person/B], actor: person/A, content: "private message", id: note/A}; {type: Like, object: note/A, to: [person/B, person/C]}
# puckipedia I think my unflattener will unflatten note/A even though person/C can't see it
# puckipedia in the inbox delivery, that is
prtksxna and timbl joined the channel
# saranix puckipedia: can you help me with the JWS? I'm trying to follow the specs but there is so many layers of dereferencing I'm going in circles
# puckipedia so the signature part, or the token part, or the key part?
# saranix all of it ;-)
# puckipedia so, I kinda mostly just used a library...
# puckipedia but I think I mostly know how it works
# puckipedia a JWT consists of three parts: a JOSE Header, an object containing claims, and a signature
# puckipedia the payload has a few default claim names, defined in RFC7519. I mostly verify iat, exp, aud, and sub
# prtksxna I found https://auth0.com/e-books/jwt-handbook helpful
# puckipedia I didn't look at it before because 'pay with a tweet', but apparently you can just fill in random info and you get a link to download the handbook
# saranix hmm... maybe I need to turn off adblock?
# puckipedia prooobably
# puckipedia anyways, then you take the key, and build a header which tells you how the payload is secured (e.g. signed with a specific alg using a specific key id). now you have two parts. you base64url-encode both of them, and put a . inbetween them
# puckipedia now you take your key, and sign this thing with the algorithm and key you determined before, and base64url-encode that value. then you add another period, and take the signature
# puckipedia and that's a JWT now
# puckipedia now, this key I use to sign server-server tokens is in the format of a json web key, which is imo the most complicated and unclear part of the spec (and it seems the spec kinda skips over it)
# puckipedia RFC7517 shows the base structure of a key, which has a keyid, and the type (RSA, Elliptic Curve, or symmetric), then RFC7518 section 6 determines the key types you can get
# saranix wow... That's even more complicated than I realized. I got stuck all the way back it "canonicalization", which from what I can tell all the specs just point in circles to each other or in many cases just dead-end at deprecated specs.... SOOO many deprecated specs
# puckipedia well, in the end it's basically
{header that is about the signature}.{list of values you want to attest}.{signature of previous parts}
# saranix "Simplicity, compactness and usability are key features of its architecture" LMFAO
# saranix I learn by seeing. Any chance you can paste all of the relevant json objects through the process?
# saranix in like a real-world object signing of an AP comms
# puckipedia so I have an example public key
{"crv":"P-256","key_ops":["sign"],"kid":"9b80748d","kty":"EC","use":"sig","x":"wNAILJvIBNZHSVd1gBPfDVPqCxby6RNBGFml6RoY7Pk","x5c":[],"y":"bwuZe1YEygjOCLDf_mxdz_1CZ6JxFiSksoZZANflc6c"}
# puckipedia this is en EC key that can be used for signing stuff, e.g. a key. the "x5c" is a side effect of the library I'm using, you can ignore it
# puckipedia note: the JWT/JWS does not actually tell you anything about the contents of the message, just that it's authorized to send messages
# puckipedia so from lol.puckipedia.com, I post an item to my outbox:
{"type": "Note", "to": "https://www.w3.org/ns/activitystreams#Public", "cc": "https://puckipedia.com/social", "content": "Now you've got JWTs"}
# puckipedia so I will make a token for sending stuff by https://lol.puckipedia.com/users/puckipedia to https://puckipedia.com/social/inbox
# puckipedia so the payload looks like this:
{"sub": "https://lol.puckipedia.com/users/puckipedia", "nbf": 1500135030, "exp": 1500135630, "aud": "https://puckipedia.com"}
# puckipedia the subject is the person that it's sending from, nbf means it isn't valid before that time (seconds since epoch), and exp means it expires 10 minutes after it was 'made'
# puckipedia the audience (aud) is set to the domain the inbox is hosted on
# puckipedia so if I want to use above key to sign it, the header would look like this:
{ "alg": "ES256", "kid": "9b80748d", "typ": "JWT" }
. I'm making a JWT, with above key ID, and algorithm ES256, aka "ECDSA using P-256 curve and SHA-256 hash algorithm"# @sckottie TIL social web protocols https://www.w3.org/TR/social-web-protocols/ (twitter.com/_/status/886255391121620992)
# puckipedia then I base64url-encode those, concatenate then with a '.' inbetween, and sign it using ECDSA and SHA-256. That signature is base64url-encoded and put in the end, and I have a token
# puckipedia eyJhbGciOiJFUzI1NiIsImtpZCI6IjliODA3NDhkIiwidHlwIjoiSldUIn0.eyJzdWIiOiJodHRwczovL2xvbC5wdWNraXBlZGlhLmNvbS91c2Vycy9wdWNraXBlZGlhIiwibmJmIjoxNTAwMTM1MDMwLCJleHAiOjE1MDAxMzU2MzAsImF1ZCI6Imh0dHBzOi8vcHVja2lwZWRpYS5jb20ifQ.Yhey0ZE5_SyftrgJOfpl74zI71j8n1BNBxoVDVupdjViD3ongk_aUxnZFA-6q_Z71GPt62zdvAmZiaMD3m2EmA
# puckipedia that token I stuff in an Authorization header (Authorization: [I current misuse 'Bearer'] [key]) and I send the request to the inbox
# puckipedia the remote server uses the kid in the header and the sub in the payload to look up the proper key, and verifies this token is properly signed. if it is, it proceeds with inbox delivery
# saranix why is the signature so short-lived? I thought spec says HTTP sig for short-lived and JWS for sigs that live with the document? and it does not seem to be signing the content at all?
# puckipedia so I think JSON-LD signatures were meant to be the long lived ones
# saranix oh right. JSON-LD uses JWS though, right? I'm not stupid for conflating them?
# puckipedia activitypub uses JSON-LD Signatures and http signatures
# puckipedia HTTP signatures basically signs a bunch of headers, one of those may or may not be the Digest: header
# puckipedia and yes, the token does not sign the content. It just tells the server that this request is properly authenticated to be sent to this server
# saranix so json-ld would be needed to do redistributions by 3rd parties. any clue how I would do that?
# puckipedia nope ... I only accept entities with IDs that share a host with the ID of the actor
# saranix hmm
# puckipedia references stay, but the receiving server will have to manually look up these entities
# saranix am I understanding correctly that keys are PRIMARY KEY(sub,kid) so that subjects can have multiple keys?
# puckipedia in my case, they are
# puckipedia I have decided not to put any limit on the kid value
# puckipedia but e.g. a server may only use one key per actor, or maybe swap them out every week
# puckipedia or use one key for the entire server, and just make each actor have the same key
# puckipedia e.g. Mastodon already has an RSA key for their stuff
# puckipedia so they could magically translate that into an RSA JWK and use it to sign JWTs for their users, and they use the actor webfinger as key id
# puckipedia yeah
# puckipedia though, having an actor is my current way to differentiate activities and objects
# puckipedia yep. That's what allows Kroeg to be incredibly flexible in allowing extensions
# puckipedia well, Kroeg itself is mostly a server :P
# puckipedia e.g. I could POST a
{type: Teleport, object: cat, target: box, actor: puckipedia}
and it'd accept it# puckipedia but if I left off the actor, it'd wrap it in a Create
# puckipedia yes
# puckipedia originally I had a hard-coded list but then that broke because Announce was added :<
# puckipedia so I have a list of known Activity types, and if you try to do e.g.
{type: Like, object: cat}
and you leave off the actor, it just errors 'hey you forgot an actor'# saranix puckipedia++
# saranix still overwhelmed but maybe a little less so
# puckipedia saranix: most large programming languages have a JOSE library
# puckipedia e.g. https://github.com/potatosalad/ruby-jose for ruby
# saranix I'm trying to do this without libraries, because there is no shortage of projects that just pull in 10,000,000,000,000,000,000,000 libraries and then become this monster that no one can read, and I'm actually trying to make a learning example
# puckipedia ah :)
# puckipedia wait, for entirety of ActivityPub or just the signing of tokens?
# saranix for AP
# puckipedia cool!
# saranix I'm calling it CraptivityPub, a craptastic impl of ActivityPub :-)
# puckipedia so one thing I haven't decided
# puckipedia currently the server->server tokens are put in Authorization: Bearer
# puckipedia but that's not really appropriate
# saranix I thought JWT has it's own auth type?
# puckipedia JWT is really just the format for the token, it doesn't tell you hwo to use it
# puckipedia the Bearer is meant mostly for c2s stuff
# saranix I'm considering whether it may be more helpful to make client and server seperate in CraptivityPub...since everyone else seems to be doing a combined thing...
# saranix I'm afraid if I make it too complicated though I may never finish it. This is one thing I definitely want to finish :/
# puckipedia saranix: so in Kroeg, the client is just a bunch of C# templates
# puckipedia and the backend just redirects unknown Accept headers to the endpoint to render the template
# puckipedia so yeah, Kroeg is really just server only
# puckipedia so Mastodon has a separate static layout, and a whole different thing for logged in
# puckipedia my idea was to build a simple ActivityStreams2-focused template library
# puckipedia React for the logged in part, yes
# puckipedia and whatever ruby library for the static templates
# saranix wasm++
# puckipedia my idea for the template language would be e.g. <div class="note">
{{$.attributedTo | render "userHeader"}}<div class="note-content">{{$.content | ishtml}}
</div></div># puckipedia which would render a subtemplate, and then render the content as HTML
# cwebber2 https://gitlab.com/dustyweb/pubstrate/blob/master/pubstrate/webapp/templates.scm#L297 just define a template for each type
# cwebber2 https://gitlab.com/dustyweb/pubstrate/blob/master/pubstrate/webapp/templates.scm#L324 and yes that is how I render tombstones currently ;P
# saranix yeah... guess there's no getting around using a lib
# saranix dangit. I hate having ginormous trees with other peoples code
# saranix it would be fine if it was like C where you just -lfoo
prtksxna and jaywink joined the channel
# saranix ugh deprecated standards strike again
# saranix it's just hell trying to find a good library
# puckipedia for what thing? (I assume you're using nodejs based on the 'tree with other peoples code')
# puckipedia currently working on a template system
# saranix hah nah. php and the evil composer virus
# puckipedia ah. I did a bunch of work on a large php backend a while back
# puckipedia okay, first prototype of the template thingy should be done. Once it works, it'll also deliver a template json object that the client can use
# Gargron puckipedia: cwebber2 hey folks can we chat about ld-signatures
# Gargron i'd hop on mumble if anyone's around
# puckipedia mm
# puckipedia I think text chat is easy enough for now?
# Gargron but typing though :weary:
# saranix I'm definitely interested in ld-sig!
# saranix but can't make voice only irc
# puckipedia so tbh LD signatures is a thing I'm not super into? tbh it's an incredibly annoying spec and assumes you know all about RDF? which tbh is kinda of annoying because JSON-LD doesn't really need you to know all that
# Gargron here is a threat model for you
# Gargron or wait
# saranix audibly gasps
# Gargron i can see working around it actually lol but here's what ld-sigs would solve
# puckipedia saranix: I'm mostly looking at the side of the average developer working on an ActivityPub client/server
# Gargron you do an Announce of a note by someone else, but the note you embed actually says something the supposed author of the note never really said
# Gargron if you had ld-sigs, you can verify instantly that it's been tampered with
# saranix puckipedia: lol I was gasping at "threat model"
# puckipedia so yeah, I ignore the contents of an object if the origin of its ID isn't the same as the origin of the actor currently authenticated for s2s messages
# Gargron however, you can also ignore embedded objects and only look and resolve their URIs
# puckipedia and the actor of the outermost object is verified against the authenticated token again
# Gargron ok yeah, that
# Gargron uhm
# Gargron i am scared of that token thing
# Gargron http signatures are ez
# puckipedia hm?
# Gargron but i have no clue about jwt-tokens or whatever they're called
# xmpp-social [ajordan] cwebber2: note that wasm is basically just faster asm.js so you don't actually have to worry about browser compat if that's what you were thinking
# puckipedia so JWT tokens are also pretty simple. they've got a header that tells you which key signed it and what algorithm it used. then a payload which is just a string->string map of 'claims', then a signature
# puckipedia there's enough libs for e.g. ruby to easily and safely generate them
Puddles joined the channel
# puckipedia aaronpk: the header can contain a 'kid'
# Gargron a "kid" xd
# puckipedia key id
# Gargron i got it
# xmpp-social [ajordan] cwebber2 I'm *sure* we've had a conversation about that before ;)
# puckipedia so, ehm, I just looked at the code of the JWT ruby lib
# puckipedia and I think the main part of it is like 51 lines for an entire module to generate JWTs
# Gargron so vampto initially suggested using http signatures for exactly the same purpose as you're using JWT
# Gargron and ActivityPub itself has no recommendations on which one to use
# Gargron i dunno how to tell which one is better
# Gargron when you validate JWT, are replay attacks validated against?
# puckipedia currently, no. but that's because I kinda forgot to implement it
# puckipedia it's a 'jti' in the claims
# xmpp-social [ajordan] cwebber2: why exactly do you need an Ajax-y endpoint?
# puckipedia oshepherd actually used it in their example
# Gargron jwt doesn't sound better to me right now
# Gargron have you considered using http sigs? the implementation was really simple
# puckipedia the JWT implementation was also really simple :)
# Gargron the http sigs spec doesn't contain things like "x5u" and "x5c"
# saranix so if one server only supports jwt and one only supports http sigs, they can't federate?
# Gargron shrug
# puckipedia Gargron: yes, but I don't use those
# Gargron nobody has implemented AP fully yet
# puckipedia looks at Kroeg
# puckipedia what I implemented is approx what oshepherd mentioned here: https://github.com/tootsuite/mastodon/issues/1557#issuecomment-298170056
# puckipedia Gargron: so a thing is that the HTTP signatures and JWT don't quite solve the same problem. JWT is basically a token that authorizes someone to POST to a specific site on behalf of a specific user
# Gargron http sigs does exactly that too
# puckipedia http signatures just .. sign the request. JWTs can contain more metadata
# Gargron it's for access control
# puckipedia cwebber2: JWT normalization? wouldn't you just take whatever is before the last period and verify that?
# Gargron http sigs = signature of chosen headers, potentially "digest" header which digests the body of the request, using a keyId, which can be a webfinger acct URI for example, or an AP URL
# puckipedia I don't sign the AS2 object
# saranix normalization of JWT is defined by the individual algo chosen
# cwebber2 https://github.com/bsletten/ruby-jsonld-signatures there's a library for it there, I haven't tried it
# Gargron i have hopped
# saranix I want to do ld-signatures but I got stuck on normalization. It points to RDF spec which doesn't seem to mention it specifically
# puckipedia btw, https://web-payments.org/vocabs/security#publicKey I think?
# saranix now I feel like I'm going backwards
# puckipedia
{"kty": "RSA", "e": "[exponent]", "use": "sig", "kid": "[your key id]", "alg": "RS256", "n": "[modulus]"}
# puckipedia https://github.com/puckipedia/Kroeg/issues/6
# saranix begs the question how long that elephant has been standing there
# saranix it should be declarable by the owner of the key how long of a ttl is acceptable for caching as well, and these values should be reasonably long like weeks not hours
# puckipedia cwebber2: oh I was wondering how I got that many inbox requests to my still-somewhat-test-instance
# puckipedia well I kinda broke OStatus federation when I started requiring JWT
# puckipedia I quickly took that off
# puckipedia I also did see a lot of instances getting my outbox.atom (which is what the atom feed federates to in my case)
# puckipedia 132 freaking instances
# puckipedia including one mysteriously using http://{}/
# puckipedia but all the way from aleph.land to xoxo.zone
prtksxna joined the channel
# Gargron puckipedia: i boosted cwebber's toot mentioning you
# Gargron i started work on inbox: https://github.com/tootsuite/mastodon/pull/4216/files with my homework on http signatures the skeleton is super simple
# Gargron however now i need to implement the full json parser to make any further progress :D
# saranix so what came out of the call? what did I miss? was there a conclusion to the ld-sig issue?
# Gargron the conclusion was "screw ld-sig for now"
# Gargron it's too complicated and it's much easier to just do a roundtrip to the original URI for now
# saranix I see...