Skip to main content

Osano Pulumi Provider for Python

Build Status License: MIT PyPI version

⚠️ Unofficial community provider

This package is not affiliated with Osano or Pulumi. It is maintained by the community and provided "as is" under the MIT license. Use GitHub Issues for support.

pulumi-osano is the Python SDK for the Osano Pulumi provider, imported as pulumi_osano. It lets you manage Osano Cookie Consent and Unified Consent workflows alongside the rest of your infrastructure-as-code. You can:

  • Create Cookie Consent configurations and rules, publish them after all dependencies settle, and export the hosted CMP script URL and exact HTML tag, so the same pipeline that provisions a website can put the consent script first in its <head>.
  • Look up the script, publish status, rules, discoveries, and audit log of any Cookie Consent configuration with get_cookie_consent_config, get_cookie_consent_configs, get_cookie_consent_rules, get_cookie_consent_discoveries, and get_cookie_consent_audit_log, for example to consume a centrally managed configuration from a website stack or to gate a switch to production mode.
  • Submit consent decisions programmatically from Pulumi deployments, including Global Privacy Control consents.
  • Query unified consent state for a subject with get_unified_consent, and resolve verified, anonymous, and session references with get_subject, get_subject_profile, and get_session.
  • Inspect UC configuration and privacy protocol collections with get_config, get_collections, and get_collection, and check for existing consent state and hashed consent profiles with check_consent and get_consent_profile.
  • Start and verify subject-profile challenges with send_subject_code and verify_subject_code. Pulumi runs functions on every preview, update, and refresh, so call these two from automation rather than declaring them in a long-lived stack; otherwise each run sends a new code.

Every function also has an _output form, such as get_cookie_consent_config_output, that accepts and returns Pulumi outputs. SDKs for Node.js, Go, .NET, and Java are also available; see the project README.

Prerequisites

  • Pulumi CLI v3+
  • Python 3.10+
  • API access to an Osano tenant: a Customer REST API key for Cookie Consent, a Unified Consent API key for Unified Consent, or both for mixed workloads

Installation

pip install pulumi-osano

In a project created with pulumi new python, add pulumi-osano to requirements.txt and run pulumi install instead.

The package declares its provider plugin, and Pulumi downloads the matching pulumi-resource-osano release from GitHub the first time you run pulumi preview or pulumi up. To install it manually, pin the version and point Pulumi at the GitHub releases:

pulumi plugin install resource osano 0.2.1 --server github://api.github.com/jflavan/pulumi-osano

Package publishing describes how each release is built and how to verify its provenance.

This program creates a Cookie Consent configuration with one rule, publishes it, and hands the script tag to the rest of the program. It assumes a project created with pulumi new python:

echo "pulumi-osano" >> requirements.txt
pulumi install
pulumi config set osano:osanoApiKey --secret   # Customer REST API key
pulumi up

__main__.py:

import hashlib
import json

import pulumi
import pulumi_osano as osano

name = "www-example-com"
domains = ["www.example.com"]
mode = "permissive"
configuration = {"storagePolicyHref": "https://www.example.com/privacy"}
rule_definitions = [
    {"store_type": "cookies", "classification": "ANALYTICS", "rule": "_ga", "rule_type": "EXACT_MATCH"},
]

config = osano.CookieConsentConfig(
    "consent", name=name, domains=domains, mode=mode, configuration=configuration)
rules = [
    osano.CookieConsentRule(
        f"rule-{i}",
        config_id=config.config_id,
        store_type=rule["store_type"],
        classification=rule["classification"],
        rule=rule["rule"],
        rule_type=rule["rule_type"],
    )
    for i, rule in enumerate(rule_definitions)
]

# Publish exactly once per change: derive the token from everything that is published.
desired = {"name": name, "domains": domains, "mode": mode,
           "configuration": configuration, "rules": rule_definitions}
publication = osano.CookieConsentPublication(
    "publication",
    config_id=config.config_id,
    change_token=hashlib.sha256(json.dumps(desired, sort_keys=True).encode()).hexdigest(),
    opts=pulumi.ResourceOptions(
        depends_on=[config, *rules],
        custom_timeouts=pulumi.CustomTimeouts(create="20m", update="20m"),
    ),
)

# Hand the tag to whatever renders or configures the site's <head>; it must come first.
pulumi.export("scriptTag", publication.script_tag)
pulumi.export("headHtml", pulumi.Output.format("<head>\n  {0}\n</head>", publication.script_tag))

pulumi preview never publishes. pulumi up creates the configuration and rule, publishes, waits for Osano to finish, and returns <script src="https://cmp.osano.com/{customerId}/{configId}/osano.js"></script>. Running it again without changes publishes nothing.

The publication exports script_src (https://cmp.osano.com/{customerId}/{configId}/osano.js) and script_tag (exactly <script src="{scriptSrc}"></script>). These installation values are deliberately non-secret. Put the tag first in the site <head> without async or defer, so the CMP loads before scripts it may control. The URL never changes between revisions, so a website only needs it once. Publication completion and CDN propagation are separate: Osano's CDN can take up to 15 minutes to serve a new revision, and browsers cache osano.js for up to 24 hours.

Read a configuration from another stack

To use the script in another stack, such as one per website, read it with get_cookie_consent_config_output instead of managing the configuration there:

consent = osano.get_cookie_consent_config_output(config_id="<config-id>")
pulumi.export("headScript", consent.script_tag)     # the same value the publication exports
pulumi.export("published", consent.publish_status)  # the URL returns 403 until the first publish

Before switching a configuration to production mode, which blocks everything unclassified, get_cookie_consent_discoveries lists what osano.js has discovered that no rule covers yet. The end-to-end workflow guide covers the whole pipeline, including Content Security Policy settings and per-environment configurations.

The Consent resource submits a consent decision, and the functions read consent state back. This program assumes a project created with pulumi new python with pulumi-osano in requirements.txt:

pulumi config set osano:unifiedConsentApiKey --secret
pulumi config set subjectRef <subject-id> --secret
pulumi config set configId <config-id>
pulumi config set privacyProtocolId <protocol-id>
pulumi up

__main__.py:

import pulumi
import pulumi_osano as osano

cfg = pulumi.Config()
subject_ref = cfg.require_secret("subjectRef")
config_id = cfg.require("configId")
privacy_protocol_id = cfg.require("privacyProtocolId")
subject_type = cfg.get("subjectType") or "verified"

subject = (
    osano.ConsentSubjectArgs(anonymous_id=subject_ref)
    if subject_type == "anonymous"
    else osano.ConsentSubjectArgs(verified_id=subject_ref)
)

consent = osano.Consent(
    "example",
    subject=subject,
    actions=[
        osano.ConsentActionArgs(target=privacy_protocol_id, vendor=config_id, action="ACCEPT"),
    ],
    attributes={"pulumiStack": pulumi.get_stack()},
    origin="api",
    tags=["demo"],
)

pulumi.export("consentId", consent.consent_id)

Destroying the stack removes the logical Pulumi resource but does not delete historical events from Osano (they are immutable).

get_subject and get_unified_consent look anonymous and verified IDs up with the default reference_type (subject); session resolves a session ID. To submit a Global Privacy Control consent, set origin="gpc" and omit actions: Osano derives the actions and the resource exports them as gpc_actions. When a pipeline submits consents on a subject's behalf, set country_code_override (and region_code_override) so Osano does not geolocate the CI runner.

Authentication

Two API keys exist:

Key Header Usage
Unified Consent API key x-uc-api-key Required for consent submissions and read operations
Osano Customer REST API key x-osano-api-key Required for Cookie Consent resources and functions; send_subject_code and verify_subject_code send every configured key, so either this key or the Unified Consent API key is enough

Configure them with Pulumi config:

pulumi config set osano:unifiedConsentApiKey --secret
pulumi config set osano:osanoApiKey --secret

Or set the OSANO_UC_API_KEY and OSANO_API_KEY environment variables, for example in CI.

Configuration

Provider-level settings (all optional):

Key Description
osano:unifiedConsentApiKey Unified Consent API key (secret); OSANO_UC_API_KEY takes precedence when set
osano:osanoApiKey Customer REST API key for Cookie Consent and subject verification (secret); OSANO_API_KEY takes precedence when set
osano:apiBaseUrl Override the Unified Consent API base URL, including any path prefix; defaults to https://uc.api.osano.com; OSANO_API_BASE_URL takes precedence when set
osano:customerBaseUrl Override the Customer REST API base URL; defaults to https://api.osano.com
osano:requestTimeoutSeconds HTTP timeout for Customer REST and Unified Consent calls, default 60 seconds; OSANO_API_TIMEOUT_SECONDS takes precedence when valid

The deprecated osano:ucApiKey and osano:ucBaseUrl keys are still read as fallbacks for unifiedConsentApiKey and apiBaseUrl.

Learn more

Release files for pulumi-osano 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pulumi-osano 0.2.1
File Size Uploaded
pulumi_osano-0.2.1.tar.gz 40.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pulumi-osano 0.2.1
File Interpreter ABI Platform
pulumi_osano-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 99.2 kB

Release files / pulumi_osano-0.2.1.tar.gz

Download URL pulumi_osano-0.2.1.tar.gz
Size 40.0 kB
Tags Source
SHA-256 checksum
How to use checksums
451eb178e58cf9d9acbad43a291836241384c2ad27e909852ab01e986eef14d9
BLAKE2b-256 checksum
How to use checksums
d8c33997b76546e3152fb90ca2e9c685d090f8b7f918832f5fced9b2c1e66a53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / pulumi_osano-0.2.1-py3-none-any.whl

Download URL pulumi_osano-0.2.1-py3-none-any.whl
Size 59.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ae21045c9bd9c0c63232dfe83ec48c52a3e639dd348de06c92ee9a83bde70d7
BLAKE2b-256 checksum
How to use checksums
dda077fa382ca4600f025636fdc4f463a0d164f15e115926a9016c857d0fae9f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page