The gcp:healthcare/consentStore:ConsentStore resource, part of the Pulumi GCP provider, defines a consent store within a healthcare dataset for tracking user consents and associated documentation. This guide focuses on three capabilities: creating consent stores in healthcare datasets, configuring consent expiration policies, and managing IAM access to consent data.
Consent stores belong to healthcare datasets and require IAM configuration for application access. The examples are intentionally small. Combine them with your own dataset infrastructure and access policies.
Create a consent store in a healthcare dataset
Healthcare applications that track user consents start by creating a consent store within an existing dataset.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const dataset = new gcp.healthcare.Dataset("dataset", {
location: "us-central1",
name: "my-dataset",
});
const my_consent = new gcp.healthcare.ConsentStore("my-consent", {
dataset: dataset.id,
name: "my-consent-store",
});
import pulumi
import pulumi_gcp as gcp
dataset = gcp.healthcare.Dataset("dataset",
location="us-central1",
name="my-dataset")
my_consent = gcp.healthcare.ConsentStore("my-consent",
dataset=dataset.id,
name="my-consent-store")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/healthcare"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dataset, err := healthcare.NewDataset(ctx, "dataset", &healthcare.DatasetArgs{
Location: pulumi.String("us-central1"),
Name: pulumi.String("my-dataset"),
})
if err != nil {
return err
}
_, err = healthcare.NewConsentStore(ctx, "my-consent", &healthcare.ConsentStoreArgs{
Dataset: dataset.ID(),
Name: pulumi.String("my-consent-store"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var dataset = new Gcp.Healthcare.Dataset("dataset", new()
{
Location = "us-central1",
Name = "my-dataset",
});
var my_consent = new Gcp.Healthcare.ConsentStore("my-consent", new()
{
Dataset = dataset.Id,
Name = "my-consent-store",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.healthcare.Dataset;
import com.pulumi.gcp.healthcare.DatasetArgs;
import com.pulumi.gcp.healthcare.ConsentStore;
import com.pulumi.gcp.healthcare.ConsentStoreArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dataset = new Dataset("dataset", DatasetArgs.builder()
.location("us-central1")
.name("my-dataset")
.build());
var my_consent = new ConsentStore("my-consent", ConsentStoreArgs.builder()
.dataset(dataset.id())
.name("my-consent-store")
.build());
}
}
resources:
dataset:
type: gcp:healthcare:Dataset
properties:
location: us-central1
name: my-dataset
my-consent:
type: gcp:healthcare:ConsentStore
properties:
dataset: ${dataset.id}
name: my-consent-store
The dataset property references the parent healthcare dataset using its full resource path. The name property sets the consent store identifier within that dataset. The store provides a namespace for organizing consent records and their documentation.
Configure consent expiration and update behavior
Organizations with consent lifecycle policies need to control how long consents remain valid and whether updates can create new records automatically.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const dataset = new gcp.healthcare.Dataset("dataset", {
location: "us-central1",
name: "my-dataset",
});
const my_consent = new gcp.healthcare.ConsentStore("my-consent", {
dataset: dataset.id,
name: "my-consent-store",
enableConsentCreateOnUpdate: true,
defaultConsentTtl: "90000s",
labels: {
label1: "labelvalue1",
},
});
import pulumi
import pulumi_gcp as gcp
dataset = gcp.healthcare.Dataset("dataset",
location="us-central1",
name="my-dataset")
my_consent = gcp.healthcare.ConsentStore("my-consent",
dataset=dataset.id,
name="my-consent-store",
enable_consent_create_on_update=True,
default_consent_ttl="90000s",
labels={
"label1": "labelvalue1",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/healthcare"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dataset, err := healthcare.NewDataset(ctx, "dataset", &healthcare.DatasetArgs{
Location: pulumi.String("us-central1"),
Name: pulumi.String("my-dataset"),
})
if err != nil {
return err
}
_, err = healthcare.NewConsentStore(ctx, "my-consent", &healthcare.ConsentStoreArgs{
Dataset: dataset.ID(),
Name: pulumi.String("my-consent-store"),
EnableConsentCreateOnUpdate: pulumi.Bool(true),
DefaultConsentTtl: pulumi.String("90000s"),
Labels: pulumi.StringMap{
"label1": pulumi.String("labelvalue1"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var dataset = new Gcp.Healthcare.Dataset("dataset", new()
{
Location = "us-central1",
Name = "my-dataset",
});
var my_consent = new Gcp.Healthcare.ConsentStore("my-consent", new()
{
Dataset = dataset.Id,
Name = "my-consent-store",
EnableConsentCreateOnUpdate = true,
DefaultConsentTtl = "90000s",
Labels =
{
{ "label1", "labelvalue1" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.healthcare.Dataset;
import com.pulumi.gcp.healthcare.DatasetArgs;
import com.pulumi.gcp.healthcare.ConsentStore;
import com.pulumi.gcp.healthcare.ConsentStoreArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dataset = new Dataset("dataset", DatasetArgs.builder()
.location("us-central1")
.name("my-dataset")
.build());
var my_consent = new ConsentStore("my-consent", ConsentStoreArgs.builder()
.dataset(dataset.id())
.name("my-consent-store")
.enableConsentCreateOnUpdate(true)
.defaultConsentTtl("90000s")
.labels(Map.of("label1", "labelvalue1"))
.build());
}
}
resources:
dataset:
type: gcp:healthcare:Dataset
properties:
location: us-central1
name: my-dataset
my-consent:
type: gcp:healthcare:ConsentStore
properties:
dataset: ${dataset.id}
name: my-consent-store
enableConsentCreateOnUpdate: true
defaultConsentTtl: 90000s
labels:
label1: labelvalue1
The defaultConsentTtl property sets the expiration time for new consents as a duration string (e.g., “90000s” for 25 hours). The enableConsentCreateOnUpdate property allows consent updates to create records if they don’t exist, simplifying application logic. The labels property adds key-value metadata for organization and filtering.
Grant service account access to consent store
Applications that read or modify consent records need IAM permissions scoped to specific consent stores.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const dataset = new gcp.healthcare.Dataset("dataset", {
location: "us-central1",
name: "my-dataset",
});
const my_consent = new gcp.healthcare.ConsentStore("my-consent", {
dataset: dataset.id,
name: "my-consent-store",
});
const test_account = new gcp.serviceaccount.Account("test-account", {
accountId: "my-account",
displayName: "Test Service Account",
});
const test_iam = new gcp.healthcare.ConsentStoreIamMember("test-iam", {
dataset: dataset.id,
consentStoreId: my_consent.name,
role: "roles/editor",
member: pulumi.interpolate`serviceAccount:${test_account.email}`,
});
import pulumi
import pulumi_gcp as gcp
dataset = gcp.healthcare.Dataset("dataset",
location="us-central1",
name="my-dataset")
my_consent = gcp.healthcare.ConsentStore("my-consent",
dataset=dataset.id,
name="my-consent-store")
test_account = gcp.serviceaccount.Account("test-account",
account_id="my-account",
display_name="Test Service Account")
test_iam = gcp.healthcare.ConsentStoreIamMember("test-iam",
dataset=dataset.id,
consent_store_id=my_consent.name,
role="roles/editor",
member=test_account.email.apply(lambda email: f"serviceAccount:{email}"))
package main
import (
"fmt"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/healthcare"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/serviceaccount"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
dataset, err := healthcare.NewDataset(ctx, "dataset", &healthcare.DatasetArgs{
Location: pulumi.String("us-central1"),
Name: pulumi.String("my-dataset"),
})
if err != nil {
return err
}
my_consent, err := healthcare.NewConsentStore(ctx, "my-consent", &healthcare.ConsentStoreArgs{
Dataset: dataset.ID(),
Name: pulumi.String("my-consent-store"),
})
if err != nil {
return err
}
test_account, err := serviceaccount.NewAccount(ctx, "test-account", &serviceaccount.AccountArgs{
AccountId: pulumi.String("my-account"),
DisplayName: pulumi.String("Test Service Account"),
})
if err != nil {
return err
}
_, err = healthcare.NewConsentStoreIamMember(ctx, "test-iam", &healthcare.ConsentStoreIamMemberArgs{
Dataset: dataset.ID(),
ConsentStoreId: my_consent.Name,
Role: pulumi.String("roles/editor"),
Member: test_account.Email.ApplyT(func(email string) (string, error) {
return fmt.Sprintf("serviceAccount:%v", email), nil
}).(pulumi.StringOutput),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var dataset = new Gcp.Healthcare.Dataset("dataset", new()
{
Location = "us-central1",
Name = "my-dataset",
});
var my_consent = new Gcp.Healthcare.ConsentStore("my-consent", new()
{
Dataset = dataset.Id,
Name = "my-consent-store",
});
var test_account = new Gcp.ServiceAccount.Account("test-account", new()
{
AccountId = "my-account",
DisplayName = "Test Service Account",
});
var test_iam = new Gcp.Healthcare.ConsentStoreIamMember("test-iam", new()
{
Dataset = dataset.Id,
ConsentStoreId = my_consent.Name,
Role = "roles/editor",
Member = test_account.Email.Apply(email => $"serviceAccount:{email}"),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.healthcare.Dataset;
import com.pulumi.gcp.healthcare.DatasetArgs;
import com.pulumi.gcp.healthcare.ConsentStore;
import com.pulumi.gcp.healthcare.ConsentStoreArgs;
import com.pulumi.gcp.serviceaccount.Account;
import com.pulumi.gcp.serviceaccount.AccountArgs;
import com.pulumi.gcp.healthcare.ConsentStoreIamMember;
import com.pulumi.gcp.healthcare.ConsentStoreIamMemberArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var dataset = new Dataset("dataset", DatasetArgs.builder()
.location("us-central1")
.name("my-dataset")
.build());
var my_consent = new ConsentStore("my-consent", ConsentStoreArgs.builder()
.dataset(dataset.id())
.name("my-consent-store")
.build());
var test_account = new Account("test-account", AccountArgs.builder()
.accountId("my-account")
.displayName("Test Service Account")
.build());
var test_iam = new ConsentStoreIamMember("test-iam", ConsentStoreIamMemberArgs.builder()
.dataset(dataset.id())
.consentStoreId(my_consent.name())
.role("roles/editor")
.member(test_account.email().applyValue(_email -> String.format("serviceAccount:%s", _email)))
.build());
}
}
resources:
dataset:
type: gcp:healthcare:Dataset
properties:
location: us-central1
name: my-dataset
my-consent:
type: gcp:healthcare:ConsentStore
properties:
dataset: ${dataset.id}
name: my-consent-store
test-account:
type: gcp:serviceaccount:Account
properties:
accountId: my-account
displayName: Test Service Account
test-iam:
type: gcp:healthcare:ConsentStoreIamMember
properties:
dataset: ${dataset.id}
consentStoreId: ${["my-consent"].name}
role: roles/editor
member: serviceAccount:${["test-account"].email}
The ConsentStoreIamMember resource grants a service account the editor role on the consent store. The member property uses the service account email in the format “serviceAccount:{email}”. This scopes permissions to the consent store rather than the entire dataset.
Beyond these examples
These snippets focus on specific consent store features: consent store creation and naming, consent lifecycle policies, and IAM access control. They’re intentionally minimal rather than full consent management systems.
The examples reference pre-existing infrastructure such as healthcare datasets (the parent resource). They focus on configuring the consent store rather than provisioning the surrounding healthcare infrastructure.
To keep things focused, common consent store patterns are omitted, including:
- Consent record creation and management (separate API operations)
- Consent policy evaluation logic
- Audit logging configuration
- Integration with FHIR stores or DICOM stores
These omissions are intentional: the goal is to illustrate how each consent store feature is wired, not provide drop-in consent management modules. See the ConsentStore resource reference for all available configuration options.
Let's create GCP Healthcare Consent Stores
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Configuration & Immutability
dataset and name properties are immutable. Changing either will force Pulumi to replace the resource.dataset must be in the format projects/{project}/locations/{location}/datasets/{dataset}.Consent Lifecycle & TTL
defaultConsentTtl must be at least 24 hours. Specify it as a duration in seconds with an ’s’ suffix, like 90000s.defaultConsentTtl only applies to new consents created after the change. Existing consents keep their original expiration time.Labels & Metadata
labels field only manages labels defined in your Pulumi configuration. Use effectiveLabels to see all labels on the resource, including those added by other clients or services.[\p{Ll}\p{Lo}][\p{Ll}\p{Lo}\p{N}_-]{0,62}. Label values are optional, 0-63 characters matching [\p{Ll}\p{Lo}\p{N}_-]{0,63}. Maximum 64 labels per store.Consent Management
enableConsentCreateOnUpdate is true, updating a consent will automatically create it if it doesn’t already exist.