Sorting out bearcaps misunderstandings

I understand the example with an password reset link (e.g. bearcap:?u=https://example.com/pwreset&t=123456) the bearcap: handler would be the browser and the browser would then transform this into an GET /pwreset HTTP/1.1 with an Authorization: Bearer 123456 request.

So, if I understand corretcly, unless the browser vendors include this, it’s not feasible to use on the client / end user layer.

Because I am not that deeply involved in the Fediverse to think of an example where you could use it in the fediverse then instead, could you maybe provide one? Just out of curiosity. :slight_smile:

Not exactly @criztovyl: the idea is that the server knows what to do with the token in t.

So a password reset example would be: bearcap:?u=https://example.com&t=123456

In the fediverse, you would use it as an object reference. For example, a non-public post could have a bearcap ID with a token.

This isn’t part of the idea at all, actually – it is just something that an implementation could do if it wanted. All a bearcap is a method for combining a URI with an access token. That’s it.

1 Like

In my head the token is a Capability URL, but indeed, the endpoint does not need to be the top-level domain: this way makes it a bit more private, since usually, an HTTPS request does not leak the path as it establishes the connection to the server before asking for it.

This means that possessing the object containing the reference is enough for getting access.
So in the end it’s then only a tool for keeping the token out of the log of the remote server?

Hmm, but the ID becomes invalid if the token is revoked.
Why not extend the AP Object and Link types with an attribute that indicates the authentication to be used to access the referenced object?
This would keep the ID URI stable.

I think this is desirable in cases of authorization. You do not want a stable ID without an authorization token; being able to refer to such an ID means you can make unauthorized references that can be passed around insecure implementations. Yes, you could extract the u parameter, but that would be an invalid ID technically (effectively a forgery).

2 Likes

I do not understand what you mean by “unauthorized references”.
I do not think that you can forbid anyone (at least not technically effective) to reference specific URIs.

Without the token you should get a 403 (or 404, depending on the implementation), so nothing is lost. And if you can retrieve the content without an token, why give out one in the first place?

Maybe it’s worth discussing what problem is to be addressed. To me this is very abstract.
I can imagine this being about something like posting a note to followers only, and only them, enforcing that using authentication and authorization somehow.
I think the “trust boundary” (?) here is the receiving server then; if you cannot trust that server to only allow the addressed users to see that note, don’t send the note there. I would even say everything else cannot be guaranteed unless you apply E2E encryption.

That’s the point entirely.

You give a separate token to each peer. If a peer does something with the token that you dislike, you can revoke that specific peer’s token. The underlying object has a stable ID, it’s not the same ID as the bearcap ID. It is allowed in JSON-LD to use references that redirect to more stable URIs.

This also allows for things like one-time-use access tokens, meaning that once an implementation has fetched the object, future fetches with that bearcap URI will not work. That means you can enforce things like making sure posts cannot be announced to new peers.

While it is true that you cannot guarantee that a given peer will not ignore the recipient list and just make the supplied object publicly visible, that object does not have a publicly accessible IDs and therefore is deniable as a spoof. It does let you guarantee that any attempt to Announce the object further through the network will fail, as neither the bearcap URI nor the stable URI are usable to fetch the object again.

Hopefully this provides a tangible example of how the construction can be used as a hardening measure.

More importantly, you can issue individualized bearcap URIs for things like inboxes upon creation of a relationship, either a server-to-server peering relationship or a person-to-person relationship (like a Follow activity). The possession of a bearcap URI to use as an inbox allows for things like very simple greylisting: if a peer (or person) possesses a bearcap, then that means they are already trusted, and we can simply bypass other forms of authentication – like HTTP signatures, which are expensive.

1 Like

I still don’t get why doing it on ID level and not AP level is better.

Like, why not just add an authentication attribute to Object (and Link; as the basic AP objects) and including the token there?

{
    "object": "bearcap:?u=https://example.com/secretpost&t=123456"
}
{
   "object": "https://example.com/secretpost",
   "authentication": {
     "token": "123456"
   }
}

Like in the latter one the ID also becomes invalid as soon as the token expires because you cannot retrieve it anymore.

One has uses outside ActivityPub. Your proposal does not.

It is better to use tools that can be shared across multiple related concerns.

If you do not have any interest in this construction, then that is fine, you are not required to implement it. I will, however, be implementing this in Pleroma. If that’s not important to you, great, then don’t implement it, but I’m not going to sit here and try to sell you on something that you clearly have no interest in.

FYI, this is similar to some JSON-LD signatures and previous ideas of naiively supporting object capabilities about a year ago. There was a lot of heated arguments. But the TL;DR is that the community is trying much less to shove ActivityPub protocol side effects into ActivityStreams itself, which presents all sorts of problems with JSON-LD parsing and understanding in order to close by-design attack vectors, and instead the community tends towards strategically leaving ActivityStreams as “simply application data” (and application side effects) and tries to improve the actual underlying protocol by utilizing orthogonal tooling to any ontology (hence efforts like Datashards, bearcap, adoption of HTTPSignatures, etc).

I think the latter is better strategically. Your idea requires parsing payloads to understand and proceed with protocol which is not a good design strategy for long term stability.

You’re free to continue going down this route in a separate thread, but to warn you, you’ll probably be treading ground where previous battles have already been resolved.

To be absolutely clear, I consider discussing alternatives to bearcaps to be off-topic for this thread. If you’re not interested in the technique, then feel free to develop alternatives. If they are better, we will consider using them. Nothing is set in stone.

But I will say that we are now two years into developing bearcaps and related technology, and that they’ve gotten a lot of people who have put a lot of effort into developing the techniques, and you’re looking at a very minor primitive of the entire package. But we want to build things that can be shared with others, so that all of the specification labor can be distributed across a wider group of participants. Specification labor requires very precise thinking, so it is good to distribute it across as wide an audience as possible.

Okay, I think I got confused by this being posted to #activitypub, (ignorantly) discussing it in that context.

Sorry for wasting (?) your time. ._.

I posted it to #activitypub because it is related to ActivityPub, namely it is a primitive that many implementations have expressed interest in using. I hope you can understand my frustration, however.

I can understand you are frustrated about that, yes.

I am still missing too much context it seems.

I recommend starting with @cwebber’s presentation found at OcapPub

2 Likes