Reliable: a spec that has been implemented (in @web3-storage/upload-api). It will change as we learn how it works in practice.
Storage providers in the w3 family of protocols need to be able to rate limit (and in many cases, fully block) abusive users from using their service. We describe a set of capabilities for tracking and administering such rate limits.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.
The rate-limit/
namespace contains capabilities relating to rate limits. It expects a resource URI identifying the service provider whose services
will be rate limited.
Delegate all capabilities in the
rate-limit/
namespace
The rate-limit/*
capability is the "top" capability of the rate-limit/*
namespace. rate-limit/*
can be delegated to a user agent, but cannot be invoked directly. Instead, it allows the agent to derive any capability in the rate-limit/
namespace, provided the resource URI matches the one in the rate-limit/*
capability delegation.
In other words, if an agent has a delegation for rate-limit/*
for a given provider URI, they can invoke any capability in the rate-limit/
namespace using that provider as the resource.
Given a subject ID (e.g., adid:mailto
, a URL, a domain name, etc), set a rate limit for the entity represented by that ID. The semantics of both the subject and rate are intentionally abstract, and the service is expected to record them without much processing.
Consumers of rate limits are expected to query the underlying data store where they are stored for the subjects they care about and interpret the rate
value in a way that makes sense for their use case.
Returns an ID that can be used to remove this limit later.
subject: string
rate: number
{
id: string
}
export const add = capability({
can: 'rate-limit/add',
with: ProviderDID,
nb: struct({
subject: Schema.string(),
rate: Schema.number()
}),
derives: (child, parent) => {
return (
and(equalWith(child, parent)) ||
and(equal(child.nb.subject, parent.nb.subject, 'subject')) ||
and(equal(child.nb.rate, parent.nb.rate, 'rate')) ||
ok({})
)
},
})
- @web3-storage/capabilities defines
rate-limit/add
capability - @web3-storage/upload-api handles
rate-limit/add
invocations
Given a subject ID (e.g., adid:mailto
, a URL, a domain name, etc), list all rate limits that apply to the given subject.
subject: string
{
limits: [
{
id: '123',
limit: 0
},
{
id: '456',
limit: 2
}
]
}
export const remove = capability({
can: 'rate-limit/list',
with: ProviderDID,
nb: struct({
subject: Schema.string()
}),
derives: (child, parent) => {
return (
and(equalWith(child, parent)) ||
and(equal(child.nb.subject, parent.nb.subject, 'subject')) ||
ok({})
)
},
})
- @web3-storage/capabilities defines
rate-limit/list
capability - @web3-storage/upload-api handles
rate-limit/list
invocations
Given a rate limit ID (returned from rate-limit/add
or rate-limit/list
), remove the identified rate limit.
id: string
{}
RateLimitsNotFound
export const remove = capability({
can: 'rate-limit/remove',
with: ProviderDID,
nb: struct({
id: Schema.string().array()
}),
derives: (child, parent) => {
return (
and(equalWith(child, parent)) ||
and(equal(child.nb.id, parent.nb.id, 'id')) ||
ok({})
)
},
})
- @web3-storage/capabilities defines
rate-limit/remove
capability - @web3-storage/upload-api handles
rate-limit/remove
invocations