Extensibility
Six primitives. Most of what you build comes from these.
Owlie's extensibility isn't a scripting feature bolted onto a fixed product. It's six first-class primitives — Resources, Functions, Forms, Hooks, Expressions, Custom Actions — each composable, each extensible in code when configuration runs out. Functions add draft, live, and rollback versioning on top.
Primitive anatomy — composite peek
Composite visual drawn from one primitive's anatomy; eventually a small live component on the curated thread.
The building blocks
Six primitives, in depth.
Each primitive earns its place by doing one thing cleanly. Each can stand alone. Every composition your business runs on is some arrangement of these six.
- 01
Resources
Anything your business grants access to.
When you reach for it
A SaaS app. A GitHub repo. A database role. A laptop order. A badge. A data room. A vendor workflow. If someone could ask "who has this?", it's a Resource. Each Resource carries its own Form, approval policy, and fulfillment path.
What it costs to use
Configuration for most shapes. Forms and Functions enter the picture when you want custom intake or custom logic.
SP-01asset pendingResource schema fragment
- 02
Functions
Sandboxed TypeScript in eight purpose-specific modes.
When you reach for it
Approval decisions that need real logic. Fulfillment for systems without a native connector. Reviewer resolution for access reviews. Event-driven and provisioning-hook automation. Admin actions on an identity or request. HTTP-style endpoint logic invoked by Owlie's control plane. Eight modes, one sandbox.
What it costs to use
A few lines of TypeScript for simple cases. More for anything that reaches out to external systems — Functions can talk to allowlisted domains and use per-version secrets.
SP-02asset pendingFunction stub — approval mode
- 03
Forms
Custom request intake per Resource.
When you reach for it
A seat type. A project code. A country. A justification. Whatever the Resource needs captured at request time, routed directly into the Function that acts on it.
What it costs to use
Pure configuration.
SP-03asset pendingForm preview — 3 fields
- 04
Hooks
Pre- and post-steps on every connector-fulfilled provisioning operation.
When you reach for it
Verify a budget before provision. Notify a manager after provision. Enrich an identity profile in between. Hooks are conditional and Function-backed — a sequence of small checks and nudges the runtime executes around each operation.
What it costs to use
Configuration for the sequence; Functions for the logic inside each step.
SP-04asset pendingHook sequence — pre + post
- 05
Expressions (OEL)
A small DSL for value transforms across the platform.
When you reach for it
identity.manager_id ?? fallback. Conditional attribute mappings. Policy predicates. OEL appears wherever a value needs to be shaped, mapped, or guarded — not where full logic is warranted.
What it costs to use
A DSL to learn. It's small. Worth it for the safety guarantees and the readability.
SP-05asset pendingOEL expressions — 2–3 examples
- 06
Custom Actions
Admin quick-action buttons on the identity and request screens, defined by you.
When you reach for it
"Reset session for this user." "Re-sync from HRIS." "Escalate this request." The things your operators do every week that would otherwise live in a runbook.
What it costs to use
A Function plus a short configuration entry.
SP-06asset pendingCustom actions bar — 4 buttons
A separate lane: connector operations
Not everything runnable is a Function you write. Connectors declare their own operations — Active Directory, for one, ships unlock-account, force-password-change, and move-to-OU. These run ad hoc against an existing assignment, on demand, with full audit, retry, and live status. They're the connector's verbs, not tenant code — a distinct lane from the Functions and Custom Actions above.
Compositions
Three things people build.
These aren't customer stories. They're compositions — small arrangements of primitives that show how the pieces fit.
A custom laptop-order workflow.
A Resource for laptop orders. A Form that captures OS and model. A Function-backed approval that checks budget. Manual fulfillment through IT's ticket queue. A Function that sends the welcome message once fulfillment completes. Every layer independently audited and traceable.
A sensitive-access policy with self-cert.
A Resource for production admin access. An approval policy where a Function decides based on identity attributes. Timed access (5 hours). A pre-revoke Hook that notifies the requester. A Custom Action on the request screen — "flag for security review" — one click for the operator, each invocation traced on the function's execution history.
An internal-system sync.
A custom Resource for an internal system. A Function-backed fulfillment path that calls the internal API and updates the downstream HR tool in the same run. No native connector, no six-figure integration project — the primitives are enough.
Where configuration ends. Where code starts.
Owlie is assembled from configuration for most workflows. Code enters when you need behavior that isn't expressible as data — a custom policy decision, a custom fulfillment path, a custom admin action. The threshold between "config-only" and "code-required" is clear and predictable. Nothing hides behind a black-box toggle.