14. Teams and sharing¶
Runnable companion:
examples/11_share_a_dataset.py
Everything you built in the previous chapters is private. A store you import into, a workset you select, a dataset you convert — they are readable by you and by nobody else, until you say otherwise.
This chapter is how you say otherwise.
A team owns it¶
A team is a named set of users. Every store, dataset and split set has exactly one owning team, recorded when it is created.
You always have at least two teams: a personal team of just you, and the
reserved global team called everyone, which every authenticated caller
belongs to.
A resource you create lands in your personal team unless you name one. There is no setting to change that — you name the team when you create the resource, where the consequence is in front of you:
Name a team explicitly when you want the work to belong to the team rather than to you:
You have to be a member of the team you name. Nothing else inherits: a store you create by copying another, or by adding samples from three others, belongs to your personal team — never to a source's.
Sharing is one thing: a grant¶
A grant binds one resource to one team at level read or write:
read lets that team read the dataset and its samples. write also lets them
write to it — attach keys, add samples — and confers read. Neither lets them
re-share it or give it away; those stay with the owning team.
Unsharing is the same verb backwards:
Publishing is a grant to everyone¶
There is no "public" flag. Publishing is a read grant to the global team, and
withdrawing is revoking it:
client.grant_resource_access("dataset", "voice_train_v1", team="everyone") # publish
client.revoke_resource_access("dataset", "voice_train_v1", team="everyone") # withdraw
Because it is an ordinary grant, it is reversible like any other, and clients
derive the label you see — private (no grants), shared (grants to named
teams), public (a grant to everyone) — from the grants alone. A write
grant to the global team is refused: implicit membership must never confer write.
Sharing a dataset is enough¶
Read access on a dataset authorizes reading its samples, without granting anything on the stores it was built from:
# `qc` can read every sample in the dataset...
client.grant_resource_access("dataset", "voice_train_v1", team="qc")
# ...and still cannot read the store it came from.
That is the common case, not a loophole — you want to share the training set, not the raw corpus. It works because a dataset is frozen: its membership was fixed at conversion, so the grant cannot silently widen later.
Building is the other way round. Creating a workset or dataset requires read access on what you are building from: each source store, or — when the source is a dataset — that dataset. And because a workset is live, it re-checks on every read: revoke a grant and the next read stops, rather than serving membership the caller can no longer reach.
From the CLI¶
datavo teams list
datavo share dataset voice_train_v1 --to qc --level read
datavo share dataset voice_train_v1 --list
datavo unshare dataset voice_train_v1 --to qc
What you learned¶
| Owning team | one per store / dataset / split set, set at creation |
| Where it lands | your personal team, unless you name one at creation |
| Grant | one resource, one team, read or write |
| Publish | a read grant to everyone; withdraw revokes it |
| Dataset read | sufficient for its samples; source access is checked when you build |
Next: 15. Shard caching and the cache hierarchy — why the second read of a dataset is free.