provrun.access
The broker decides whether a run may use one URI in one mode, and returns a
grant. A grant names the decision, not a credential. Later brokers will read
profiles and identities; StubBroker checks an allow list and the
environment, and grants only reads: a read-only snapshot of an input, and a
read of one version of the run’s experiment.
The modes:
mounted_snapshot: a read-only snapshot of an input, staged for the agent.pinned_read: provrun reads one version of a catalog object itself, as it reads the run’s experiment. The agent never sees it.mounted_readwrite,retrievalandapi: kept for later brokers; the stub grants none of them.
A run asks for its experiment before its run folder is made, so the broker
decides it with a RunScope, which has the run’s ID, org, domain,
environment and actor, and the run records the grant once it has opened.
The stub’s rules:
- The URI, without its selector, must be in the allow list, or under a folder
in it. An allow entry that ends with
/is a folder. - A URI with a selector, such as
?at=branch:prod, must be in the allow list with that same selector. A selector can name another branch, and in a logical scheme the branch is often the environment, so a selector that the list does not name could reach another environment. - A logical URI has the form
scheme://org/domain/env/.... Its org and its environment must be those of the run. - A physical URI, such as
file:///..., names no environment, so the stub grants one only in the dev environment. A scheme is physical if it names a store of the catalog, including one that the configuration adds, such aslakefs-acmein the example configuration.
class AccessDenied
AccessDenied(grant: Grant)A broker refused a request. The error holds the deny, as a grant.
| Parameter | Type | Default | Description |
|---|---|---|---|
grant |
Grant | required | The deny: a grant whose decision is “deny”, with its reason |
class Grant
Grant(id: str, uri: str, mode: str, decision: str, reason: str, expires_at: str | None, policy: str)A broker’s decision on one request: a URI in one mode.
It names the decision, not a credential.
| Parameter | Type | Default | Description |
|---|---|---|---|
id |
str | required | The grant’s ID, such as grant-0a1b2c3d4e5f, which the evidence records |
uri |
str | required | The URI asked for |
mode |
str | required | The access mode asked for, one of the modes the module lists |
decision |
str | required | “grant” or “deny” |
reason |
str | required | Why the broker decided so |
expires_at |
str | None | required | When a grant ends, as an ISO 8601 time; None for a deny, or a grant with no end |
policy |
str | required | The policy that decided, such as “stub” |
Grant.as_dict
Grant.as_dict() -> dictThe grant as the data of an access_granted or access_denied event: every field but the URI.
| Parameter | Type | Default | Description |
|---|---|---|---|
| returns | dict | The grant’s ID, mode, decision, reason, expiry and policy, under the names the evidence uses |
class RunScope
RunScope(run_id: str, org: str, domain: str, env: str, actor: str)Who asks, for a request decided before the run opens.
It has the fields of a RunContext that a broker reads.
| Parameter | Type | Default | Description |
|---|---|---|---|
run_id |
str | required | The ID that the run will have |
org |
str | required | The run’s org |
domain |
str | required | The run’s domain |
env |
str | required | The run’s environment, such as dev or prod |
actor |
str | required | Who runs it |
class Broker
Decides whether a run may use one URI in one mode.
A broker defines decide. request and record write the
evidence around it; decide_early writes nothing. All three raise
AccessDenied on a deny.
Broker.request
Broker.request(ctx: RunContext, uri: str, mode: str, purpose: str = '') -> GrantDecide one request and write its evidence.
It writes access_requested, then access_granted or access_denied. Raises AccessDenied on a deny.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run that asks |
uri |
str | required | The URI it asks for |
mode |
str | required | The access mode, one of the modes the module lists; another raises ValueError |
purpose |
str | '' |
Why, such as the agent’s name; access_requested records it |
| returns | Grant | The grant |
Broker.decide_early
Broker.decide_early(scope: RunScope, uri: str, mode: str, purpose: str = '') -> GrantDecide one request before the run opens, and write nothing.
Raises AccessDenied on a deny, and ValueError for a grant whose expiry
is not an ISO 8601 time. The run writes the grant with record. It
calls decide with scope, so a broker’s decide must read only the
fields that a RunScope has; and it does not go through request, so a
broker that changes request must change these two methods too.
| Parameter | Type | Default | Description |
|---|---|---|---|
scope |
RunScope | required | Who asks, as the run will be once it opens |
uri |
str | required | The URI asked for, such as the run’s experiment |
mode |
str | required | The access mode, one of the modes the module lists; another raises ValueError |
purpose |
str | '' |
Why, such as “experiment” |
| returns | Grant | The grant |
Broker.record
Broker.record(ctx: RunContext, grant: Grant, purpose: str = '') -> NoneWrite the evidence of a decision made before the run opened.
The decision is a grant that decide_early gave, or the deny in the AccessDenied that it raised. A deny, and a grant that has expired since, are written as access_denied, and raise AccessDenied.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | required | The run, now open |
grant |
Grant | required | The decision that decide_early made: its grant, or the deny in its AccessDenied |
purpose |
str | '' |
Why, as given to decide_early; access_requested records it |
Broker.decide
Broker.decide(ctx: RunContext | RunScope, uri: str, mode: str, purpose: str) -> GrantMake the decision for one request, and write nothing.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | RunScope | required | The run’s context, or a RunScope before the run opens |
uri |
str | required | The URI asked for |
mode |
str | required | The access mode asked for |
purpose |
str | required | Why, as the caller gave it |
| returns | Grant | The decision, a grant or a deny; it writes nothing and raises nothing for a deny |
class StubBroker
StubBroker(allow: Iterable[str], *, physical_schemes: Iterable[str], ttl: timedelta = datetime.timedelta(seconds=3600))A broker that checks an allow list and the environment.
It follows the rules the module lists, and grants only mounted_snapshot and pinned_read.
| Parameter | Type | Default | Description |
|---|---|---|---|
allow |
Iterable[str] | required | The URIs, and the folders, ending in /, that a run may read |
physical_schemes |
Iterable[str] | required | The schemes that name a store of the catalog, such as catalog.stores.keys() |
ttl |
timedelta | datetime.timedelta(seconds=3600) |
How long a grant lasts |
StubBroker.decide
StubBroker.decide(ctx: RunContext | RunScope, uri: str, mode: str, purpose: str) -> GrantDecide one request by the stub’s rules, which the module lists.
| Parameter | Type | Default | Description |
|---|---|---|---|
ctx |
RunContext | RunScope | required | The run’s context, or a RunScope before the run opens; the stub reads env and org |
uri |
str | required | The URI asked for |
mode |
str | required | The access mode asked for; the stub grants only mounted_snapshot and pinned_read |
purpose |
str | required | Why, as the caller gave it; the stub does not read it |
| returns | Grant | A grant with policy “stub”, which ends after ttl, or a deny that says why |