Silicon IAMDocs

IAM integration for Honeycomb

IAM accepts authentication configuration and enforces current identity, consent, organization and provider permissions. Honeycomb owns the app catalog, review workflow, releases, bundle editing and shared test-environment coordination. The canonical wire contract is OpenAPI; the stateless Rust entry point is silicon_iam_client::honeycomb::ManagementClient.

Provision the integration

Migrate both IAM databases and apply deploy/postgres/runtime-grants.sql to each. Keep the production and testing databases separate. The API uses its restricted runtime role; bootstrap uses operator database authority.

Once an active Carbon owner and organization exist, provision the two initial app identities without a catalog:

iam-bootstrap-apps --org-id '<org>' --carbon-id '<owner>' \
  --iam-app-id '<org>iam' --honeycomb-app-id '<org>honeycomb' \
  --output /secure/operator/iam-honeycomb-bootstrap.json

Use the normal IAM encryption/keyring settings and an operator IAM_DATABASE_URL. The command creates a private, exclusive output file before committing changes. Retain that same file across retries. Existing app IDs and credentials are preserved; new app secrets appear only for newly created identities. The file contains a separate random hck_ service credential and an independent management notification signing key. Deliver them through deployment secret storage. Do not put this file in a release archive or repository.

Honeycomb's authentication app declares self.identity.read, self.profile.read and self.membership.read. Enable self.tags.read when tag disclosure is needed. New scopes require renewed user consent; adding an app permission never expands previously issued tokens. Unscoped token introspection discloses organization roles through self.membership.read, intersected with current application approval and that session's live consent. The historical roles.read scope does not grant role disclosure, and memberships.read does not grant tag disclosure. Tags require self.tags.read in the token, current app approval and live consent. Bootstrap seeds identity, profile and membership access only for a new Honeycomb identity; update existing app records and optional tag access through the authorized configuration flow.

Configure the IAM API:

Configure the IAM worker independently:

The worker does not require the service credential. App webhook URLs and keys do not control management notifications. Initial signup, login, backend deployment and direct CLI installation work before Honeycomb exists. See CLI packaging and direct installation.

Authentication and mutation envelope

All /api/v1/honeycomb/* requests use Authorization: Bearer hck_…. Ordinary ask_, user tokens and test root keys never grant this authority. Do not send X-Testing-Environment-Key; test instructions name their environment explicitly.

Human-authored writes use X-Honeycomb-Actor-Token: oat_…, a live Carbon token whose client and audience are the provisioned Honeycomb identity. IAM checks the current session, selected organization grant, live membership and required manager/reviewer authority. A supplied identity or role is not proof. Silicons cannot act as organization owners/admins in this IAM contract.

Writes carry an operation_id UUID, Idempotency-Key and expected_iam_revision (zero only when creating). Keep the exact serialized body, operation ID and key for retries. Keys are bound to service, actor, operation, resource and body. Changed content conflicts. IAM revisions are read from IAM; configuration_revision is Honeycomb's increasing configuration number. Neither is a release version, and revisions need not increase by exactly one. Production configuration uses absent/null environment_id. Publication planning uses request_id as its durable operation identity; subsequent decisions and activation have distinct operation_id values. Some service-only control reads and exports have no user actor, as specified below.

Sensitive mutations require X-Step-Up-Token, obtained through the existing IAM verified-channel flow for the same actor session, action and application UUID:

Mutation Step-up action
App secret rotation application.client_secret.rotate
Webhook destination approval application.webhook.approve
Webhook signing-secret rotation application.webhook_secret.rotate

An authorized retry of a completed operation does not consume a second proof. The mutation response has Idempotency-Replayed. Secrets are encrypted for a 10-minute replay window; afterward the original durable receipt remains. Retrying the mutation returns secret_replay_expired: true without generating new credentials. Reconciliation and notifications never contain secrets. Recover a lost expired secret with a new explicitly authorized rotation.

Accepted app and bundle configuration

Method and path, relative to /api/v1/honeycomb Purpose
GET /scope-catalog?org_id=…&app_id=… Current scope definitions, review requirements and organization eligibility; filters optional
PUT /applications/{app_id}/configuration Accept identity-bound authentication configuration
POST /applications/{app_id}/scope-decisions Record an exact live provider/IAM reviewer decision
POST /applications/{app_id}/webhook-approvals Activate the exact pending destination
POST /applications/{app_id}/secret-rotations Rotate the app credential once
POST /applications/{app_id}/webhook-secret-rotations Rotate supplied signing material, with ten-minute old-key overlap
PUT /bundles/{bundle_id}/configuration Accept eligible same-organization app membership or deletion
GET /applications/{app_id} Current accepted record and revisions
GET /bundles/{bundle_id} Current accepted bundle, including deletion state
GET /operations/{operation_id} Durable progress and secret-free result
GET /inventory?kind=applications|bundles|testing-environments Adoption inventory; paginate with returned next_after as after

IDs and owning organizations are immutable. Changing metadata does not rotate an app credential. The backend origin is optional without OBO endpoints; OBO requires a valid origin. Endpoint paths remain immutable. ttl_seconds is a positive integer with default 300. Existing proofs keep their original expiry; new proofs use the newly accepted duration, and verification remains one-use.

Private apps require live owning-organization membership and the selected grant through login, exchange, refresh, introspection, API access and OBO. Their critical-scope exemption is recorded separately from provider approval. Private apps are excluded from anonymous discovery. Public publication uses the immutable review flow below. A public proposal sent to /configuration remains pending without overwriting accepted configuration; publication_approved: true cannot authorize publication. New app identities must first be registered privately. A completed proposal can still have state: pending; the separate activation accepts its reviewed configuration.

GET /applications/{app_id} includes authoritative webhook_url and pending_webhook_url; absent destinations are null. It never returns the signing key. An app without any webhook remains listable with a disabled webhook and secret version zero. A changed webhook URL stays pending until its stepped-up approval. The previous active receiver remains active. An unchanged URL can omit its secret; changing that secret uses the dedicated rotation operation. Bundle acceptance remains subject to IAM's current eligibility checks; catalog publication cannot override them. Bundle membership creates no new credential or principal.

Immutable publication and notification recipients

All paths below are relative to /api/v1/honeycomb. Review plans contain exact provider/scopes gates derived from IAM's current catalog. Resolve provider app IDs and origins from accepted configuration and catalog records; do not embed particular organization/app handles in business logic.

Method and path Request and authority
POST /applications/{app_id}/publication-plans Owner/admin actor; request_id, app_id, configuration_revision, configuration, visibility: public
GET /publication-plans/{plan_id} Service read of the immutable plan
GET /publication-plans/{plan_id}/reviewer-eligibility?provider=… Service plus proposed reviewer actor; returns current eligible
POST /applications/{app_id}/publication-decisions Live reviewer; operation_id, request_id, plan_id, app_id, configuration_revision, exact provider/scopes, decision: approve|deny, optional reason
POST /applications/{app_id}/publication-activations Owner/admin actor; exact request/plan/app/configuration revision and configuration, visibility: public, current expected_iam_revision, decision_ids, optional configuration_operations
GET /publication-plans/{plan_id}/notification-recipients?provider=… Service-only recipients for a plan gate, or provider=owners for the applicant organization's owners/admins
GET /organizations/{org_id}/notification-recipients Service-only current owners/admins for that organization's operational notices

The configuration uses the accepted configuration shape, with availability: active. Envelope app ID, visibility and configuration revision may be repeated inside it but must agree. Plans bind the complete normalized configuration, including supplied webhook signing material. Changing it requires a new plan. Retain the returned plan_id, gates and reused_approvals. Existing live provider approvals can satisfy matching critical scopes without a duplicate review, but IAM records the exact evidence and rechecks it later.

Review authority is distinct from applicant administration:

Copy each gate's exact scope list. Activation requires the latest approving decision for every outstanding gate, rejects duplicate or mismatched decision IDs, and rechecks reviewer membership/capabilities, catalog requirements and scope revocation. configuration_operations names only pending /configuration operations for this same app, revision and configuration digest; their durable receipts become accepted in the activation transaction. The result includes a strictly newer iam_revision, effective_configuration, request_id, plan_id and publication_request_id. Reconcile against the current app record: its publication_request_id becomes null when its review evidence is no longer current.

Recipient responses contain only eligible principal IDs and verified primary emails, scoped to the requested organization or plan gate. Use after with the returned next_cursor; limit defaults to 100 and is bounded to 1–1000. Recipient discovery does not grant approval authority. Honeycomb owns sending its notices.

Shared testing keys and authority

Testing always has an explicit environment identity. There is no global testing key or deployment-wide switch that grants test access. Honeycomb supplies a random 32-character ASCII alphanumeric root key for each new environment and shares that exact key/version only with the participating services. IAM encrypts its copy and binds runtime requests to the selected environment, generation and key version. Invalid test context never falls back to production.

These header credentials have different purposes:

Header Authority
Authorization: Bearer hck_… Honeycomb service transport for all management routes
X-Honeycomb-Actor-Token: oat_… Live Carbon creator/owner/admin or reviewer authority
X-Honeycomb-Application-Authorization: Basic … Base64 of the production app_id:app_secret; IAM verifies it as an ordinary production app client
X-Honeycomb-Testing-Key: … A specific environment's current root key; alone authorizes public imports/key rotation/clean, or with production app credentials proves attachment
X-Testing-Environment-Key: … Ordinary runtime test requests only; forbidden on Honeycomb management routes

Use either actor or production application authorization, never both. An environment root key alone can authorize import, rotate-key and clean, always with Honeycomb service authentication and exact expected_key_version, generation and expected_iam_revision. This grants no private production app visibility. No separate credential enables testing. The service-only GET /application-identity with production application authorization returns the verified app/organization IDs and current IAM revision without a secret. It does not accept a supplied identity as proof.

A production app may create an environment in its own organization and becomes its application owner. It may manage that environment even after its test key is disabled. A different app may attach/import only itself by presenting that environment's root key and its own valid production credentials, including across organizations. Attachment grants neither lifecycle ownership nor another app's test credential. Its private dependencies still require the appropriate source-organization authority. GET /testing-environments with production app authorization lists owned and attached environments, with can_manage reflecting actual ownership; it supports status, cursor and limit pagination.

IAM-local testing lifecycle

Send POST /testing-environments/{environment_id}/operations with explicit environment_id, current generation, expected_iam_revision, operation_id and operation. Reconcile with GET /testing-environments/{environment_id}. An actor needs a live selected grant in the owning organization and, for an existing environment, creator or owner/admin authority. Application authority follows the ownership/attachment rules above.

Operation IAM behavior
prepare New UUID, IAM revision 0, generation 1, org_id/name, supplied testing_key and key_version: 1; returns that key while runtime remains disabled
import Accepts app_id and exact source_revisions for its dependency graph; works in prepared, cleaned or active environments
activate Enables prepared/cleaned IAM state after Honeycomb confirms every participant is ready
activate-apps In an active environment, enables only the exact pending app_ids after shared readiness
rotate-key Supplies fresh testing_key, next key_version and current expected_key_version; leaves prepared state until shared activation; old or retired key material cannot be reused
disable Blocks runtime access and retains recoverable IAM data
restore Changes disabled state to prepared; activation is still explicit
clean Blocks access, advances generation once, erases IAM's isolated data and leaves cleaned state
purge Requires disabled access; erases IAM data/keys and leaves a completion tombstone

For Honeycomb-coordinated creation/rotation, always supply the shared key and version. Omitting key material remains compatible with old IAM-generated-key clients; independent participant-generated keys cannot form a shared environment. testing_key/new key_version are accepted only for fresh prepare or rotation. Existing legacy prepare preserves its original key. expected_key_version can also guard other existing-environment lifecycle instructions.

source_revisions are IAM production application versions, distinct from Honeycomb configuration revisions. Supply the complete dependency graph, including the requested root. Imports retain each source's accepted public/private visibility; read the returned IAM configuration instead of assuming every imported app is private.

Imports preserve existing pinned source revisions and credentials. Adding an app to an active environment leaves already-ready apps working; new imports remain pending until activate-apps. To refresh particular imports, include only their IDs in refresh_app_ids and supply the exact resulting graph source_revisions. The refresh changes those selected pins, preserves their application IDs and rotates their test credentials. Unselected existing imports keep their pins and credentials. Refresh targets must belong to the requested dependency graph.

Source snapshots are encrypted and retained across interrupted imports. The receipt returns imports with accepted revisions/configuration and readiness, plus only the requested root app's app_secret; dependency credentials are not returned. Same-operation retries reuse committed target identities and secrets. Cleaned imports receive fresh credentials. Imported production webhook signing material remains marked inherited and is never disclosed as a test-owned key.

Lifecycle reservations commit before target-plane work. Retry the exact pending operation after transport/process failure; a different operation conflicts until it completes. User/app authority is checked again before replay. Renewed user tokens may resume the same actor's operation. Service-only reconciliation remains available when test sessions/root keys are invalid.

With IAM_HONEYCOMB_SCHEDULED_TESTING explicitly enabled, the service may author clean/disable/restore/purge/activate/activate-apps for its managed environments without inventing a user actor. The flag does not grant runtime testing access, app ownership or permission to prepare/import/rotate arbitrary environments.

iam_completion: true acknowledges only IAM's work. Honeycomb must collect all participant receipts before shared activation or reporting a shared clean/purge complete. IAM has no independent idle-retirement or purge worker. Generation and key-version fences reject stale requests. Signed test webhook metadata supports direct environment_id and positive generation; the SDK also accepts legacy aggregate placement and rejects conflicting direct/aggregate values.

Test application administration

These routes address only the named isolated environment:

Method and path under /testing-environments/{environment_id} Purpose
GET /applications/{app_id} Accepted test configuration and active destination; no signing/app secret
PUT /applications/{app_id}/configuration Configure an existing test app or register a new test-only private app
POST /applications/{app_id}/secret-rotations Explicit test credential rotation
POST /applications/{app_id}/credential-recovery Production app retrieves only its own current test credential without rotating it

Reads require query fields generation, key_version and expected_environment_revision. Writes carry those same fields, environment_id, operation_id, the target app's expected_iam_revision, and configuration_revision. Configuration writes additionally carry configuration; rotation omits it and names the current configuration revision. Environment and application revisions are separate preconditions.

Service-only reads are secret-free. Configuration and secret rotation also accept ManagementAuthority::Environment with the current root key, generation, key version and environment revision; this grants authority only inside that environment. Test login tokens must never be presented as production actor tokens. Other writes require the live human environment manager or a production app acting on only its own immutable source identity; an attached app additionally presents the matching root key. Environment ownership does not let a production app read or change another app's credential. A human environment manager registers new test-only apps. Registration uses revision zero, requires private visibility and an app ID in the environment's owning organization. The configuration accepts the ordinary IAM authentication fields; a new webhook destination needs its signing secret. Existing app configuration preserves its app credential; a new registration or explicit rotation returns one protected app_secret. Configuration changes leave that app pending coordinated activation. Target-plane receipts prevent a lost production commit from rotating twice.

Credential recovery requires service plus production app authorization, and the root key for an attached app. Its body carries operation_id, environment_id, generation, key_version and expected_environment_revision. It validates the current production source UUID and returns only that app's existing credential. A fresh recovery operation can recover a lost credential after an earlier replay window expired; it never rotates the secret.

Exact application retention

POST /testing-environments/{environment_id}/retention is a service-only, scheduled-testing-gated instruction with operation_id, environment_id, Honeycomb's environment_revision, IAM's expected_iam_revision, current generation/key_version, and 1–100 unique retired_apps IDs. IAM verifies exact production links or actual applications in the named testing plane; it does not accept a caller-asserted app identity as environment authority.

IAM erases only those apps and their dependent IAM rows, including credentials, and marks matching production links retired. Sibling apps, shared identities and other environments remain intact. Test-only apps are supported. A target-plane receipt commits with erasure so a retry after a lost control-plane commit cannot erase a subsequently imported app again. The response echoes the requested IDs, Honeycomb revision, generation and key version, returns current iam_revision and iam_completion: true, and remains an IAM-local state: accepted receipt. Honeycomb separately coordinates each participating service's owned data.

Notifications, reconciliation and adoption

The management envelope contains event_id, operation_id, resource_id, environment_id, revision, event_type and secret-free data. Verify the raw body before JSON parsing. X-IAM-Management-Signature is t=<unix-seconds>,v1=<hex-HMAC-SHA256(timestamp + "." + raw-body)>. Use honeycomb::verify_notification, a bounded timestamp tolerance, durable event ID deduplication and per-resource revision ordering. Respond 2xx only after durable receipt. IAM retries failed delivery with backoff; redirects are not followed.

GET /events?after=<event-id> reads the durable archive. POST /events/{event_id}/replay queues that same event again. Archive/inventory UUID pagination is not a transactional change cursor: concurrent commits may appear behind a cursor. Use notifications plus periodic full inventory/current record reconciliation, including after a disconnected period.

Roll out databases and IAM first, then provision the API integration and worker subscription when Honeycomb's adapter is ready. Enabling IAM_HONEYCOMB_RETIRE_LEGACY_WRITERS=true retires legacy production app/bundle/review/test lifecycle writers with 410 management_moved_to_honeycomb; IAM's identity, login and runtime APIs stay available. The new console directs users to Honeycomb for the moved management surfaces; retain the existing frontend until those replacement flows are ready.

Enumerate existing records, preserve IDs and read current revisions. For each retained environment, call service-authorized POST /testing-environments/{environment_id}/adoption-export with operation_id, expected_iam_revision and an idempotency key. The protected response contains the unchanged root key, owner IDs, source/target app links, retention metadata, accepted import/configuration revisions and credential versions. The export does not rotate credentials or change ownership. Its key is excluded from durable public receipts and notifications; secret response replay lasts ten minutes. Store the transferred root key in Honeycomb's encrypted per-environment storage.

Existing apps retain their current visibility, IDs, credentials and accepted scopes. Unadopted environments have state legacy; submit prepare with their current IAM revision and generation to adopt them while preserving their root key and active/disabled state. Test database upgrades include isolation for the new management tables. Stage the writer switch with Honeycomb; do not create duplicate identities to work around an unconfigured adapter.

Cutover acceptance

Deploying IAM contracts does not establish cross-service readiness. Keep legacy writer retirement and automatic scheduled testing disabled until Honeycomb's replacement flows pass authenticated end-to-end checks: owner/app authority, reviewer decisions and revocation, exact publication activation, webhook approval, lost-response reconciliation, additive import and key/generation fencing, adoption preserving credentials, and coordinated retention/recovery. These checks must exercise actual configured participant apps and services. Missing participant transport stays unavailable; it must not trigger a global test unlock, production fallback or recreated legacy identity.

Install the CLI

curl -fsSL https://docs.iam.teamofsilicons.com/install.sh | sh