Share an S3 dataset with an outside partner
Keep a research or imaging dataset in the customer’s own S3 bucket and share it with a person at an outside partner. The partner’s person holds a vendor seat in the tenant.
Who does each step:
| Step | Who |
|---|---|
| 1. Register the dataset | An Owner or Admin |
| 2. Add the partner and invite a seat | An Owner or Admin |
| 3. Share the dataset | A domain owner of the dataset |
The samples use the allowed helper from Access decisions.
1. Register the dataset on S3
The Seald Healthcare Cloud holds the bucket binding and its AWS role. No device ever holds them.
await allowed(await client.datasets.register({ name: 'imaging', classification: 'phi', storage: { kind: 'object-storage' }, storageBinding: { s3: { bucket: 'example-health-imaging', prefix: 'sealdhealthcare/', region: 'us-east-1', role: 'arn:aws:iam::123456789012:role/sealdhealthcare-cloud' } }, indexFields: ['modality', 'study_date'], segmentFields: [], retentionFloor: sixYears, firstOwner: alice,}));_ = try await allowed(client.datasets.register(DatasetRegistration( name: "imaging", classification: .phi, storage: Dataset.Storage(kind: .objectStorage), indexFields: ["modality", "study_date"], segmentFields: [], retentionFloor: sixYears, storageBinding: .s3(S3Binding(bucket: "example-health-imaging", prefix: "sealdhealthcare/", region: "us-east-1", role: "arn:aws:iam::123456789012:role/sealdhealthcare-cloud")), firstOwner: alice)))allowed(client.datasets.register(DatasetRegistration( name = "imaging", classification = Classification.PHI, storage = Dataset.Storage(kind = Dataset.Kind.OBJECT_STORAGE), indexFields = listOf("modality", "study_date"), segmentFields = emptyList(), retentionFloor = sixYears, storageBinding = StorageBinding.S3(S3Binding(bucket = "example-health-imaging", prefix = "sealdhealthcare/", region = "us-east-1", role = "arn:aws:iam::123456789012:role/sealdhealthcare-cloud")), firstOwner = alice)))firstOwner becomes the dataset’s first domain owner.
2. Add the partner as a vendor and invite a seat
vendors.record records the partner’s contract. people.invite with the vendorId invites one person as a seat.
VendorEntryDraft field | What it sets |
|---|---|
name | The partner’s name. |
contract | The contract’s reference, startsAt and endsAt. At its end, the seats are offboarded. |
baa | The BAA’s terms, or null. Without a BAA in force, seats never reach PHI. |
reach | The datasets and actions the seats may ever be given. Include imaging. |
seats | How many people may hold a seat at once. |
signIn | Where the seats sign in. |
responsible | The person answerable for the partner. |
const vendor = await allowed(await client.vendors.record(draft));if (vendor) await allowed(await client.people.invite([{ email: 'j.ortiz@partner.example', roles: ['employee'], vendorId: vendor.vendorId }]));if let vendor = try await allowed(client.vendors.record(draft)) { _ = try await allowed(client.people.invite([InvitationDraft(email: "j.ortiz@partner.example", roles: ["employee"], vendorId: vendor.vendorId)]))}allowed(client.vendors.record(draft))?.let { vendor -> allowed(client.people.invite(listOf(InvitationDraft(email = "j.ortiz@partner.example", roles = listOf("employee"), vendorId = vendor.vendorId))))}The person enrolls a device on the invitation. See Enroll a device.
3. Share the dataset with the seat
await allowed(await client.domains.share(imaging.root, { person: seat }));_ = try await allowed(client.domains.share(imaging.root, to: .person(seat)))allowed(client.domains.share(imaging.root, to = ShareTarget.ToPerson(seat)))| Deny reason | When |
|---|---|
vendor | The dataset is outside the vendor’s reach, or it holds PHI and no BAA is in force. |
Next
- Datasets on S3 for how each operation reaches the bucket.
- Remove a colleague’s access to end the partner’s access early.