Skip to main content

Consent and handling banners

client.security exposes the five existing security-display routes. It is separate from client.markings, which manages resource marking metadata.

config = client.security.get_admin_config()
public = client.security.get_public_config()
script = client.security.get_embed_script()
print(config.banner_enabled, public.banner_top_text, script.content_type)

Admin reads retain configured content even when its feature is disabled. Public reads omit disabled consent/banner values and apply bottom-banner fallbacks. They are cached briefly in each Core process; a caller may observe the previous public values immediately after a write. Responses retain unknown fields and marking-provider presentation metadata. The SDK does not render or execute HTML or the returned JavaScript, and it does not set browser session storage. The script metadata preserves headers received over HTTP; middleware may replace the script handler's cache policy.

Explicit full replacement​

SecurityDisplayUpdate requires both flags and accepts six nullable values. Omitted optional values are sent as null and cleared, so preserve fields you intend to keep. Blank optional strings normalize to null; colors must be six-digit hexadecimal values. Core sanitizes consent HTML.

from kamiwaza_sdk.schemas.security_display import SecurityDisplayUpdate

original = client.security.get_admin_config()
fields = original.model_dump(include=set(SecurityDisplayUpdate.model_fields))
update = SecurityDisplayUpdate.model_validate({
**fields,
"banner_enabled": True,
"banner_top_text": "EVALUATION ONLY",
"banner_top_color": "#123456",
})
# Execute only after the administrator approves the complete replacement.
effective = client.security.update_config(update)
print(effective.banner_enabled, effective.banner_top_text)

Nonblank deployment environment values and a configured consent file take precedence over stored admin settings. A successful PUT can therefore return different effective flags or text. Do not infer successful activation from HTTP success alone. Restoring a prior value also writes audit metadata; there is no SDK operation to erase configuration/audit history.

Call client.security.accept_consent() only after the user accepts the displayed terms. Its receipt does not grant authorization or prove a complete durable per-user ledger. Repeating it can produce repeated audit events. Both this call and configuration writes require approval in the agent-tool surface.

Public methods skip authentication refresh, but retain headers already present on the client. For anonymous pre-login behavior, use an independently created unauthenticated client rather than a previously signed-in session. Rate-limit responses remain errors; the SDK does not claim browser acceptance when a call fails.

The integration node changes global settings only with explicit disposable-host opt-in, an operator-confirmed absence of overrides, and a private restoration journal. It validates API state and responses; browser behavior remains covered by the separate existing browser tests and roadmap UI arm.

Live Chrome display replay​

tests/integration/test_security_display_browser_live.py reuses the owned display fixture and its restoration journal. It supplies only an embedding HTML document; the deployed script, public configuration, and successful consent POST use real HTTPS responses. It checks click blocking, explicit acceptance, banner text and color, reload persistence, a fresh session, and disabled configuration. It also drives the deployed legacy login screen and confirms its pre-login gate, banners, and reload persistence. Explicit browser-side network aborts exercise the embed script’s fail-closed configuration retry and its documented admission after a failed acceptance request; those failures are injected, not server outages.

Install the optional Python playwright package and Google Chrome before this replay. Chrome must trust the deployment certificate independently of the SDK's CA bundle. Check this before changing display configuration; do not disable certificate validation to make the test pass. Use the API suite's disposable identity opt-in, owned deployment, cleared operator overrides, and new private KAMIWAZA_TEST_SECURITY_JOURNAL path prefix. Each test appends a SHA-256 hash of its pytest node ID, retaining a separate private recovery journal. Use a fresh prefix per batch; existing prefix files or per-test journals are never overwritten. Tests that change global display settings must run sequentially. Restore original database-row existence and operator configuration after the fixture restores the API values.

python -m pytest tests/integration/test_security_display_browser_live.py --tb=short \
--evidence-map tests/e2e/security_display_chrome_map.yaml --emit-evidence

This supporting check does not establish audit durability, proxy identity, rate-limit thresholds, concurrent administration, authenticated frontend behavior, or frontend clients other than the deployed legacy client. The registered composite first runs the existing API assertions, then the browser assertions with the same owned fixture. The superseding registry is tests/e2e/scoped/security-display-chrome-134.kit.json; emitted evidence retains these unverified groups. Assess the five canonical supported operations without representing these broader limits as executed.

Canonical-operation replay​

security_display_canonical_map.yaml pairs with scoped/security-display-canonical-134.kit.json. It uses the same complete composite and all five canonical supported operations. The earlier map remains unchanged: it records broader untested groups as skipped required operations, so even a passing test emits an incomplete capability result. The canonical map keeps those groups as explicit registry scope limits, consistent with the Kit's supported-operations acceptance contract. It does not claim those groups were executed or erase the earlier incomplete record.