What are projects doing about LD-Signatures since https://w3id.org/security/v1 went away?

The title should be self-explanatory to anybody working with LD-Signatures. The URL that defines the context for LD signatures (https://w3id.org/security/v1) is gone. So is v2.

How are you verifying LD signatures without it?

1 Like

Started digging deeper and there is a redirect - but the php json-ld library doesn’t do redirects. Sorry for the noise.

Nope. Still a problem.

get: error: https://web-payments.org/contexts/identity-v1.jsonld: Failed to connect to web-payments.org port 443: No route to host.

from my end, it looks like https://w3id.org/security/v1 redirects to https://w3c-ccg.github.io/security-vocab/contexts/security-v1.jsonld which loads fine. not sure where web-payments.org comes into any of this…

Yes, same. Repo: https://github.com/w3c-ccg/security-vocab

1 Like

Apparently it’s github that returns the web-payments redirect, but this doesn’t appear to be consistent and may depend on who is asking for it. So here we are once again staring into an opaque Microsoft blob and wondering what they’re doing and why.

[If it were the first time, I’d say it’s probably just a simple little bug. This is soooo not the first time.]

Think I’ll play around with the user-agent string and see if the results change. Otherwise, we’ve got a cached copy on our older sites, but I’ll probably have to stick a copy in the repo and seed the cache during installation for any new sites that may be affected.

Oh! I think I might know what’s going on. The Security V1 loads fine. It’s the Identity V1 context that fails to load: https://w3id.org/identity/v1 redirects to the web-payments domain which no longer resolves. So yes, any LD-signed activity that references the context https://w3id.org/identity/v1 will break.

Somewhat fortunately, the only properties that are used for LD Signatures are dc:creator, dc:created, sec:signature, and sec:signatureValue – all of which are defined in the Security V1 context. So you could probably rewrite https://w3id.org/identity/v1 wherever it occurs and replace it with https://w3id.org/security/v1.

Unfortunately, that still leaves RsaSignature2017 completely undefined. You could maybe define it in an inline context extension, mapping it to the sec: namespace just like we all lie to ourselves with as:Hashtag or as:sensitive or as:manuallyApprovesFollowers. Alternatively, if you instead inject https://w3id.org/security/v2, then you gain access to all of Security V1 and also RsaSignature2018, which doesn’t help you unless you also rewrite RsaSignature2017 to RsaSignature2018 (and then rewrite it back before distribution, because Mastodon is hardcoded to only accept RsaSignature2017…)

More generally, this just goes to show that we should try to migrate away from using LD Signatures as soon as possible, since the draft they are based on was obsoleted several times over. You may consider FEP-8b32 as a proposal to adopt VCDI 1.0 proof, which is defined in https://w3id.org/security/data-integrity/v1 currently.


Thanks for the deep dive. I’ve had real life sucking up my spare cycles and wasn’t able to investigate. I started on FEP-8b32 some time ago to port our existing nomadic identity framework – but the fact that it currently breaks federation with the elephant in the room is an important consideration. Maybe I’ll just build it all on the Nomad side - and enable it on ActivityPub behind a feature toggle. We’re using salmon signatures in Nomad currently (remember those?) because I saw this train wreck coming years ago.


General note about remote JSON-LD contexts (or about immutable normative resources in general): implementations should use a cached value of these, not dereference the URI everytime they are using it.

There are many good reasons for that, including:

  • privacy (your users do not want w3id.org or any other server to be pinged everytime they use your implementation)
  • security (relying on a 3rd party resource is an attack vector)
  • financial and environmental cost (you spend money and energy to retrieve a content that is essentially always the same, and specified by the standard you are implementing)

The fact that these contexts are available online is a convenience (for testing, discovering…) but should not be a requirement of any robust implementation.

json-ld contexts aren’t immutable

yes you shouldn’t be fetching them every time, yes you can cache them with a very long ttl, but not forever. also in order to use a json-ld context you have to fetch it at least once; if it isn’t available anymore, you end with a situation like this one re: https://w3id.org/identity/v1 (which no longer resolves to anything, so good luck tracking down a static copy i guess)

however, you might say that a versioned context is immutable, so the “identity v1” context should still be the same no matter where you get it from. but you still have to find it and get it before you can store it. therefore it makes sense to stop using it or referring to it, or if you care to do so, then you can rewrite it to something more durable.

In general they are not, of course. But we are talking here about a context that is (intended to become) normative, i.e. part of a standard (more precisely: a specific version of the standard), and as such, is not expected to change. So I argue that the good practice would be for implementations of the standard to come with a local copy of that context.

I don’t mean to minimize the social hassle of https://w3id.org/identity/v1 being broken. My point was that robust implementations should not rely on it being always available.

(Note that the Verifiable Credential context is repeated in the spec, precisely to make the spec self-sufficient and not depending on what the context URI dereferences to.

Yes, I’m aware of the need for caching these resources. We’ve been caching them since 2017. But we didn’t seed the cache for new sites - so we did need to dereference the URI and fetch it once (and then refresh the cache every few days in case it changed). I’ve now added seed documents for new sites.

But this signature mechanism really just needs to be eradicated. We’ve had signatures for years that don’t require external resources to validate and LD-signatures are just a train wreck. So are http-signatures by the way. It can be claimed that that is another topic but it’s really not.

The whole security framework of the fediverse is basically built on sand castles.

1 Like

@macgirvin I would appreciate your feedback on FEP-8b32, especially on the subject of canonicalization algorithm. The concept of “cryptosuite” is central to Data Integrity spec, and that means we need to decide which algorithms we want to use. W3C-VC workgroup is aware of this proposal and I think they can help with standardization of a chosen cryptosuite, so this time we could have stable foundation to build upon.

One of my former co-workers from Netscape came up with salmon signatures when he went to work for Google, and it’s bloody brilliant. The signature includes a base-64-url’d copy of the exact payload that was signed. This is what you verify – and if it verifies, you can replace the activity payload with what was signed to ensure there was no mangling. The data type doesn’t matter. Could be JSON, plaintext, XML, HTML, RFC822, anything. You don’t need to parse JSON and put it in some predictable order through canonicalisation/normalisation. You just verify the signature and replace any payload (which is optional at this point) with the payload you verified. No external fetches of anything are required. No centralised resources required. What’s even more brilliant is that individual objects can be signed. They don’t have to be entire activities.

I actually don’t care what crypto-suite is used. These tend to be short-lived anyway and probably shouldn’t be hard-wired.

Yes, but we need to start with one cryptosuite to make our implementations interoperable.

This is a nice low-tech solution but it works on plaintext and that could lead to various inefficiencies. Example: I received a signed activity and need to forward it, but the destination is unreachable at the moment, so I save that signed activity to database. Several hours later the destination node comes online and now I need to find activities awaiting delivery. If activities are stored as plaintext, it could be difficult to find the right ones without additional indexes. Meahwhile, JSON objects are searchable (and you can deserialize/serialize signed JSON documents without invalidating the signature).

if you mean Magic Signatures - diaspora* federation protocol then i had a look at that and i think the general principle is sound, but i’m not entirely sure how it might apply to linked data. you may need multiple signatures, as the signature would apply to an individual node on the graph rather than to one whole self-containing document.

I would argue again that implementing LD-signature (or any JSON-LD based specification) should not be considered as “requiring external resources to validate”. The JSON-LD context is frozen by the standard, therefore its value should be considered fixed, and can (probably must) therefore be embedded in the implementation.

Furthermore, many implementation of such JSON-LD standard work directly on the JSON data without using the context to expand the data – which is a valid way of working with JSON-LD data as long as you are interested only in a closed vocabulary.

The JSON-LD context is frozen by the standard

Sorry but I just spit out my coffee reading this and had to grab another keyboard. Welcome to the fediverse.