Product updates
What we've shipped, and when.
A running log of what's landed in the codebase. Honest dates, real scope, no vaporware.
Entries before public launch are build milestones — real work, dated when it landed in the codebase. After launch, entries are release announcements.
March 2026
Access reviews and the in-app connector builder
Certification campaigns with reviewer accountability and exportable evidence. Plus a web UI for building connectors against internal systems.
Two big pieces before the final pre-launch pass.
Access review campaign + in-app connector builder
Two-up: review campaign overview with reviewer completion status, and the in-app connector builder mid-configuration.
Access reviews
- Certification campaigns with configurable scope — by user set, by resource set, or both
- Reviewer accountability — each reviewer sees only their slice of the campaign
- Completion tracking + exportable artifacts (scope, reviewers, decisions, resulting changes)
- Revocations that flow from a review run travel the same provisioning pipeline as any other access change
- Campaign artifacts attach to the evidence layer for audit
In-app connector builder
- A web UI inside the admin dashboard for building new connectors against internal or long-tail systems
- Configuration-driven: auth (OAuth 2.0, API key, JWT, or custom flow via Function), entity schemas, field mappings via OEL
- Functions fill in the behaviors that don’t fit a config field — a few lines of TypeScript, sandboxed, version-managed
- AI assistance where the target system has public documentation — schema inference, auth detection, boilerplate scaffolding
- Turns what used to be a six-figure services engagement into a configuration task
Next entry will be the early-access launch itself. That one waits.
February 2026
Timed access, optimistic approvals, and custom actions
High-risk access with self-cert extensions. Provision-first-then-approve flows. And Function-backed admin buttons on any entity screen.
Three features, one theme: the platform shapes itself around the workflow, not the other way around.
Self-cert prompt for expiring access
User-facing self-cert prompt 28 minutes before expiry: "Your access is about to expire. Extend for 2 more hours?"
Timed access with self-certification
- Any Resource can carry an expiry policy — five hours of production admin access, seventy-two hours of data-room access, whatever fits
- Before expiry, the user gets a self-cert prompt — “your access expires in 28 minutes, extend?”
- Extension is a policy decision: auto-approve, re-run approval, or deny
- Expired access revokes through the same provisioning pipeline as any other change, same audit trail
Optimistic approvals
- Provision first, approve after — admin-controlled, rule-based, or AI-assisted
- If the eventual approval denies, revoke happens automatically through the pipeline
- Used for high-confidence flows where blocking on approval adds friction without adding safety
Custom actions
- Admin quick-action buttons on any entity screen — identities, resources, requests, tickets, assignments
- Each action is a Function-backed operation
- Scoped per-entity, per-page
- Extensibility at the UI surface, not just the data model
These are the features that look small on paper and make the biggest difference in practice.
December 2025
Identity attribute governance and the Owlie Expression Language
Per-attribute source-of-truth rules with multi-system priority fallback. And OEL — a small DSL that shows up everywhere attributes move.
Real-world identity attributes come from multiple systems — HRIS for name and title, directory for email, custom apps for cost centers. Owlie now handles this honestly.
Attribute source-of-truth rules
Attribute governance config: email prefers Workday, falls back to Google Workspace. Provenance shown per value.
Identity attribute governance
- Per-attribute source-of-truth rules (e.g. email prefers Workday, falls back to Google Workspace)
- Multi-system priority fallback when the preferred source is missing or stale
- Full provenance — Owlie tracks which system each value came from
- Conflict resolution is a policy, not an accident
Owlie Expression Language (OEL)
- A small DSL for value mappings, attribute transforms, and fallback rules
- Used throughout the platform — attribute maps, approval policies, connector schemas, fulfillment rules
- Safe evaluation — no arbitrary code execution surface
- Zero-config where possible — inline inside configuration
These two features are quiet, but they’re load-bearing. Every identity attribute flowing through the platform touches at least one of them.
November 2025
KMS, execution journals, and evidence as architecture
`kms-svc` lands with tenant-scoped, context-bound encryption. And the execution journal becomes the platform's audit trail by construction.
The trust plumbing. The invisible foundation under every claim the platform makes about auditability.
Evidence: per-step journal + actual-state snapshot
End-to-end operation view: execution journal, actual-state snapshot, atomic apply-and-project confirmation.
KMS
- Tenant-scoped encryption for every secret — connector credentials, OAuth client secrets, Function secrets, settings secrets
- Context-bound decryption: ciphertext bound to tenant + declared usage context. Cross-tenant or cross-workflow replay fails closed at decryption time
- Structured decryption justifications — opaque secret reads are not allowed. A service requests decryption with a structured reason, and it’s recorded
- Tenant key rotation: future writes move to the new key version; old ciphertext stays decryptable with its original version until a caller re-encrypts
- AWS KMS anchors the service’s top-level trust; tenant-level operations are served through the internal KMS layer
- Per-tenant key creation on first use — no manual setup step before storing the first secret for a tenant
- Audit trail of every encryption, decryption, and rotation with caller identity and declared purpose
Provisioning evidence
- Per-step execution journal, with retried and superseded states preserved (not overwritten)
- Actual-state snapshot persisted alongside applied-version advance — in the same transaction
- Identity graph projection written into the shared graph atomically with apply
- Callback delivery to originating services with target-version + applied-version + correlation ID
- Real-time UI events on the tenant channel so dashboards reflect operation status without polling
The underlying promise: “what we applied” cannot drift from “what we recorded as applied.”
September 2025
Auth0, BambooHR, and the connector SDK formalized
Two more connectors land — Auth0 for customer identity, BambooHR for HRIS lifecycle signals. The connector SDK gets a formal contract.
Connector coverage expands from workforce identity to customer identity and HRIS.
Auth0
- Sync: users, organizations, roles
- Provision: full account lifecycle + entitlement grants (organization memberships, role assignments)
BambooHR
- Sync only: employee records — HRIS lifecycle signals and identity attributes
- Deliberately narrow scope. BambooHR owns the truth on HR events; provisioning flows from there, not the other way around
Also in this milestone:
- Connector SDK formalized: lifecycle hooks, HTTP destination policy, response parsing contracts, error taxonomy mapping
- Membrane-based manifest generator scaffolded — parses existing connector bundles into draft Owlie manifests with inferred entities, schemas, and auth hints (not live at launch; future-ready)
- Catalog quality gates: published definitions, schema partitioning, and implementation verified together at install time
- Upgrade-compatibility checks during manifest reconciliation — catalog drift surfaces early, not after a partial integration goes live
Four native connectors total: Google Workspace, Microsoft Entra ID, Auth0, BambooHR.
August 2025
Functions: a real runtime for tenant-authored logic
`func-svc` goes live. Sandboxed TypeScript in four purpose-specific modes, with draft-vs-live release management and version-scoped secrets.
The extensibility layer. Every subsequent differentiator in the platform hangs off this.
Function editor
Function editor showing a draft approval-mode Function, version list, publish-to-live control, and the separate draft below.
- Four function modes: endpoint handlers, approval logic, fulfillment logic, custom admin actions. Each starts from a purpose-specific template
- Single editable draft per function with inline build feedback — save incrementally, retry until runnable
- Publish-to-live with new-draft-on-publish: live code stays immutable while editing continues separately against a fresh draft
- Rollback to any prior live version without rebuilding from scratch
- Version-scoped secrets: add and remove on drafts; rotate values on published versions without republishing code
- Allowlisted outbound network: no general-purpose internet by default. When enabled, limited to explicitly approved public hostnames (including subdomains)
- Fail-closed runtime validation: missing, inconsistent, or non-publishable releases don’t execute
- Execution history with outcome, timing, version identity, and bounded captured console output
- Version-targeted test execution for controlled inspection without changing what’s live
- Function purpose is fixed at creation time — it’s a design constraint, not an oversight
Decisions that matter: drafts and lives are separate. Published releases are immutable code (secrets can still rotate). Outbound is opt-in, never implicit.
July 2025
Sync that verifies reality, not just inventories it
`sync-svc` ships with policy-driven drift handling and the stale-not-delete rule. Sync is an input to control, not just observation.
Sync in Owlie does more than import data. It observes reality, compares it to intended state, and applies the policy you set when the two diverge.
Drift detected
Drift-detected card: observed vs. desired state, policy chip (FLAG / ADOPT / PRESERVE / IGNORE), operator actions.
- Connector-driven sync coverage — sync jobs are created automatically from connector manifests
- Flexible run scheduling: scheduled full syncs, incremental where the source supports change markers, and manual-only for operator control
- Dependency-aware relationship ordering — memberships wait for their object runs to finish first, so relationships land against a complete graph
- Policy-driven drift handling: adopt, flag, preserve, or ignore — configurable per assignment
- Stale-not-delete: provisioned records that disappear from a sync run are marked stale, not hard-deleted. Protects against sync-feed hiccups wiping records
- Authoritative full-state cleanup: soft-delete for sync-only objects that disappeared; preserve-with-stale-flag for provisioned objects
- Identity matching + creation: match-and-update, create-if-unknown, or flag-if-ambiguous — per sync-job configuration
- Assignment linking: adopt, ignore, or flag on match-without-existing-assignment
- Detailed run history with phase progression, checkpoints, record-level outcomes, and archived long-term storage
- Actionable failure reporting — operators can usually tell from the error whether they need to fix credentials, scopes, config, or retry
The shared graph_nodes / graph_edges model went in with sync and is where both sync and provisioning write. Single source of truth for “who has what.”
May 2025
Native connectors: Google Workspace and Microsoft Entra ID
The first two production connectors. Full lifecycle management for the two systems most mid-market teams already depend on.
Connector one and two. Picked deliberately — Google Workspace and Microsoft Entra ID cover the workforce-identity root for most mid-market teams.
Connected integrations
Google Workspace and Microsoft Entra ID connected, showing synced users/groups, provisioning targets, and the admin-action menu.
Google Workspace
- Sync: users, groups, admin roles, org units, domains
- Provision: full account lifecycle + entitlement grants (groups, admin roles)
- Custom actions: move a user to another org unit, sign a user out of active sessions
Microsoft Entra ID
- Sync: users, groups, group membership
- Provision: full account lifecycle + entitlement grants (group membership)
Also in this milestone:
- Versioned integration catalog — installable manifests per connector, resolved at install / upgrade time
- Standardized connection setup: OAuth 2.0 authorization code, client credentials, JWT bearer, and API key patterns
- Host-managed provider credentials for Google Workspace — a shared OAuth app, so tenants don’t each register their own
- Per-field schema semantics: identifier, read-only, sensitive, immutable, create-only-writable, required-for-action
- Entity schema validation at resolve time — bad desired state is rejected before the target system is ever called
Narrow and deep. No wide-and-shallow catalog theater.
April 2025
Provisioning that converges instead of racing
`prov-svc` lands. Operations are intent-based and versioned — retries, overlap, and partial failure converge deterministically.
The provisioning engine. This is the deepest technical piece in the platform, and it went green today.
Execution journal for an operation
Per-step execution journal of a recent provisioning operation: status, timing, error context, superseded markers.
- Typed operation intents: provision, enable, disable, revoke, update attributes, add/remove/set entitlements — each with per-action payload validation
desired_versionandapplied_versionper assignment — concurrent or retried operations converge by version, not by timing luck- Pre-flight + no-re-create invariant: when observed state is unknown or stale, read first, then plan. Once adoption happens, account creation cannot re-enter the plan. Protects against the classic duplicate-account-on-retry failure mode
- Idempotent submission with caller-supplied or auto-derived keys (scoped to tenant + identity + resource + action)
- Operation-centric retry: one idempotent lever handles every stuck state
- Structured connector error taxonomy: auth errors never retry; rate limits always do; others follow connector guidance. Retry logic is consistent across integrations
- Per-step execution journal: status, timing, error context, superseded markers for plan changes
- Atomic apply + graph projection in one transaction — “what we think we applied” cannot drift from “what we recorded as applied”
- Callback delivery back to the originating service on terminal states, with target-version, applied-version, correlation ID, and any final error
- Real-time operation status events on the tenant channel
The line that matters most in the whole system: every operation carries a target version.
March 2025
Access requests, tickets, and approval chains
`request-svc` went green. Multi-resource requests, sequential approval chains, routed tickets, and a lifecycle model that handles partial outcomes honestly.
request-svc — the request-workflow coordinator — shipped. It accepts a submitted request, resolves approval paths, opens approval work for humans, hands approved resources to fulfillment, and aggregates everything into a single request-level outcome.
Request detail with approval chain
Multi-resource request showing per-resource outcomes, sequential approval chain, routed tickets, and retryable error recovery.
- Multi-resource requests with per-resource outcome tracking: a single request can end in full success, full rejection, or partial — each case handled honestly
- Sequential approval chains: advance only after the current step is approved or reassigned
- Routed tickets for human approvers: named users, groups, or the beneficiary’s manager
- Manager-fallback routing for identities with missing or invalid manager data
- Policy-driven approval decisions via Function: auto-approve, auto-reject, or delegate to a specific user or group
- Retryable error recovery for missing approvers, bad manager routing, and downstream failures — operators don’t recreate a request to recover
- Reassignment-aware progression: continues approval after reassignment without rebuilding the request
- Lifecycle event publishing for downstream dashboards, notifications, and automation
A request only settles once every requested resource reaches a terminal state. No “mostly succeeded” final statuses.
January 2025
Resources that aren't just apps
A Resource is anything with a 'who has this?' question. Each one carries its own request form, approval flow, and fulfillment path.
Most governance tools model “apps” and “entitlements.” Owlie models Resources — and a Resource is whatever you need it to be. This is the conceptual core of the platform, and it landed today.
Resource definition
A Resource's shape: name, type, custom Form reference, approval policy, fulfillment path. One screen, the whole composition.
- Abstract Resource primitive: request intake, approval policy, fulfillment path, and metadata bundled together
- Approval steps can be humans, groups, manager routing with fallback, or Function-backed logic
- Fulfillment paths: connector-automated, manual ticket to a user or group, Function-backed, or virtual (no external side effect)
- Per-Resource custom request Forms — collect the data that matters for that Resource, not the vendor’s default schema
allow_multipleflag for Resources that can be granted more than once per identity- Metadata JSONB for open-ended attributes without schema migrations
- Type field for categorization
Example shapes modeled in the first week: SaaS access, GitHub repos, database roles, laptop orders, shared data rooms, vendor onboarding steps, physical badges.
December 2024
MFA, passkeys, and zero-knowledge passwords
TOTP, WebAuthn passkeys, and a zero-knowledge password option. Plus policy-driven MFA with grace periods for staged rollouts.
The auth surface got serious. Three login methods that cover the range from familiar to phishing-resistant, and a policy layer that lets tenants stage MFA rollouts instead of flipping a switch.
MFA enrollment during login
Authenticator-app setup with QR code, first-code verification, and backup-code display — all inside the required-MFA login journey.
- TOTP (RFC 6238): 30-second window, 6 digits, 10 single-use backup codes (SHA-256 hashed)
- WebAuthn passkeys: challenge-response via
@simplewebauthn, replay protection via signature counter, challenges stored with 5-minute TTL - Zero-knowledge password login: raw password never leaves the browser during authentication
- Policy-driven MFA: required / optional / admin-only per tenant policy, with grace periods for staged rollout
- In-flow MFA enrollment — users can set up a factor during their first required login, without a separate setup process
- MFA secrets AES-GCM encrypted using an HKDF-derived key from
COOKIE_SECRET; no plaintext in the DB
Detail: backup codes are hashed and consumed once. A used code is gone. Passkeys track sign-count to detect replay.
November 2024
Authentication that branches on tenant policy
Password and magic-link sign-in, tenant-scoped sessions, and the first shape of a policy-gated login journey.
auth-svc took its first real shape. Tenant-branded sign-in, password and magic-link login, and the beginnings of a login journey that can insert extra steps — MFA, terms acknowledgment, profile completion — before issuing a session.
- Password login with scrypt hashing (CPU cost 16384, 32-byte derived key, 16-byte salt)
- Timing-safe dummy verification to prevent user-enumeration via timing attacks
- Magic-link sign-in for passwordless flows
- Tenant-scoped sessions with sliding-window renewal and a hard maximum lifetime
- Delegated request authentication — other Owlie services validate incoming requests through this service, not their own
- API key authentication for automation callers, tied to an identity + tenant
The decision: authentication is a pipeline, not a form. Other services borrow authentication state; they don’t reimplement it.
October 2024
Foundations: multi-tenant architecture on the edge
The infrastructure bet. Subdomain-based multi-tenancy, edge-friendly Postgres pooling, and a service-to-service control plane.
The core bet: every tenant gets its own subdomain, every request routes through a tenant-resolution layer, and every database query is scoped by tenant_id by default. Zero cross-tenant data access, enforced at the query-builder level. Everything after this is built on it.
- Subdomain-based tenant routing (
acme.owlie.com,corp.owlie.com) - PostgreSQL via Hyperdrive for edge-friendly connection pooling
- Cloudflare Workers for global edge deployment
- Service-to-service RPC bindings as the internal control plane
- Monorepo scaffold — shared
db,service,utils,errors,worker,test-utils,uipackages - Typed error classes with client-safe messages and HTTP status mapping
The significant decision: tenant scoping is architectural, not a check you remember to write.
Want to keep up?
Subscribe to the RSS feed, or request early access to see what's next.