Quick Start: Your First Authorization Check
Welcome to Housecarl. This guide walks through sign-up, CLI setup, a simple policy, and a live authorization check.
What You'll Learn
By the end of this guide, you'll have:
- A Housecarl account with a tenant
- The housectl CLI installed and configured
- Your first authorization policy
- Performed a live authorization check
Step 1: Sign Up
Head over to ui.authz.housecarl.cloud and sign up. You have two options:
Email Signup
- Click "Sign up with Email"
- Enter your email address and create a password
- Check your email for verification link
- Click the link to verify your account
- Choose a name for your organization (this creates your tenant)
Google OAuth
- Click "Sign up with Google"
- Select your Google account
- Choose a name for your organization (this creates your tenant)
When you create your tenant, Housecarl automatically sets up:
- A "root" domain for your policies
- Starter policies that grant you full access
- Everything you need to start working immediately
For details on what gets created, see Tenant Management.
Step 2: Install housectl
The housectl CLI is your primary tool for managing Housecarl and testing authorization.
Prebuilt GitHub release binaries are not currently published. Build housectl from source:
git clone https://github.com/upside-down-research/code.git
cd code
# Build with Bazel
./bzsh build //housecarl:housectl
# Optional shortcut
# make cli
# Install it somewhere on your PATH
sudo install -m 0755 ./bazel-bin/housecarl/housectl /usr/local/bin/housectl
Verify Installation
housectl --version
This should print the installed housectl version.
Step 3: Login
Connect housectl to your Housecarl account:
housectl config login https://api.authz.housecarl.cloud your-email@example.com --tenant your-org-name
You'll be prompted for your password. Enter it (it won't be displayed).
Successful login prints a status block similar to:
Logged in: yes
Username: your-email@example.com
Tenant: your-org-name
housectl also prints a separate line noting that the generated context was saved and set as current.
Note: Replace your-email@example.com with your actual email and your-org-name with the tenant name you chose during signup.
Troubleshooting: If you see authentication failed, confirm the tenant name is correct and that your user is associated with that tenant. If you’re not sure, ask your tenant admin or support to verify the association.
Verify Your Session
housectl config ping
Expected output:
Logged in: yes
Troubleshooting: If you see Logged in: no, log in again. If you need a basic server reachability check instead of a session check, run housectl config health.
Step 4: Create Your First Policy
Let's create a policy that allows users in the "engineering" team to read documents in the "project-alpha" folder.
Create a Domain for This Example
We'll create a dedicated domain for the project-alpha folder so the example is fully isolated.
housectl domain create project-alpha
Now list your domains and copy the UUID for project-alpha:
housectl domain list
You'll use that UUID in the policy and request examples below.
Create a Policy File
Create a file called my-first-policy.toml:
name = "engineering-read-project-alpha"
description = "Allow engineering team to read project-alpha documents"
engine = "Glob"
deny = false
invert = false
[[statements]]
group = "engineering"
action = "read"
object = "hc://domain/<project-alpha-domain-uuid>/documents/project-alpha/*"
What this policy means:
- name: A unique identifier for the policy
- engine: "Glob" lets us use wildcards like
* - deny: false means this is an "allow" policy
- statements: The actual rules
- If the user's
groupattribute is "engineering" - AND they're trying to "read"
- AND the resource starts with "hc://domain/
/documents/project-alpha/" - THEN allow the request
- If the user's
Add the Policy to Your Domain
Now deploy the policy to your project-alpha domain (replace the UUID with your project-alpha domain's UUID):
housectl domain put-policies <project-alpha-domain-uuid> my-first-policy.toml
Expected output:
Successfully updated 1 policies
Step 5: Test Authorization
Now let's test if our policy works! We'll create an authorization request and check it.
Create a Request File
Create a file called auth-request.json:
{
"context": {
"subject": {"Single": "user:alice"},
"action": {"Single": "read"},
"object": {"Single": "hc://domain/<project-alpha-domain-uuid>/documents/project-alpha/budget.xlsx"},
"group": {"Single": "engineering"}
}
}
What this request means:
- User "alice" wants to "read"
- The document at "hc://domain/
/documents/project-alpha/budget.xlsx" - Alice has the attribute "group: engineering"
Note: housectl authz can-i expects RequestValue wrappers (Single/Multiple) as shown above. The REST API accepts plain string values (no wrappers). In both cases, all attributes belong under context.
Check Authorization
housectl authz can-i auth-request.json
Expected output:
ALLOW
Success! Alice can read the document because she's in the engineering group and the resource matches our policy.
Try a Denied Request
What if Alice tries to write the document instead of reading? Create auth-request-denied.json:
{
"context": {
"subject": {"Single": "user:alice"},
"action": {"Single": "write"},
"object": {"Single": "hc://domain/<project-alpha-domain-uuid>/documents/project-alpha/budget.xlsx"},
"group": {"Single": "engineering"}
}
}
Check it:
housectl authz can-i auth-request-denied.json
Expected output:
DENY
Alice is denied because our policy only allows "read" actions, not "write".
What Just Happened?
Congratulations! You just:
- Signed up for Housecarl and got a tenant
- Installed and configured housectl
- Created an authorization policy using glob patterns
- Tested authorization requests and saw both ALLOW and DENY responses
Next Steps
Now that you've got the basics, here's where to go from here:
Understanding Concepts
- Tenant & Domain Policy - How domains and inheritance work
- Domain Model - Core objects and relationships
- Policy Language - Syntax and evaluation engines
Administration
- Tenant Management - Managing tenants and users
- Policy Administration - Advanced policy creation
- Policy Cookbook - Real-world policy patterns
Developer Integration
- Housecarl API - Integrate with your app
- Authorization Requests - Request structure and patterns
- Developer Cookbook - Practical integration examples
Deep Dives
- Tenant & Domain Policy - Domain hierarchy and inheritance
- Domain Model - How everything fits together
- housectl Reference - Complete CLI documentation
Common Questions
Q: What if I want to allow Alice to write as well?
Add "write" to the action pattern:
"action": "read|write"
Or create a separate policy for write access.
Q: How do I add more users to my tenant?
housectl user create bob Secret456! bob@example.com
housectl tenant associate-user your-org-name bob
Security note: Passing passwords as command-line arguments exposes them in shell history and process listings. In sensitive environments, disable shell history before running this command, or use a secrets manager to supply the value.
Q: Can I test policies without deploying them first?
Yes! Use housectl authz can-i-local:
housectl authz can-i-local --request auth-request.json my-first-policy.toml
This tests entirely offline without touching the server.
Q: What's this "hc://" prefix in the object?
That's the Housecarl resource URI format. It always starts with hc:// followed by the resource type and path. Think of it like http:// but for authorization resources.
Q: My authorization check says DENY but I think it should allow. How do I debug?
Check these in order:
- Is your policy actually deployed?
housectl domain list-policies root - Does the request exactly match the policy? Pattern matching is precise.
- Is the user associated with the tenant?
housectl tenant is-user-associated your-org-name alice - Check the evaluation engine - Glob patterns don't cross
/boundaries
See Policy Administration for more debugging tips.
What's Different About Housecarl?
If you've used other authorization systems, here are the key differences:
- Tenant-Scoped: Everything is isolated by tenant. Multi-tenancy is built in from the ground up.
- Domain Hierarchies: Policies live in domains that can inherit from each other. This lets you organize policies logically.
- Four Evaluation Engines: Choose between Fixed (exact), Prefix, Glob (wildcards), or RegEx based on your needs.
- JWT + Request Signing: Authentication uses signed JWT tokens with tenant context embedded, and protected REST/gRPC calls also carry request signatures derived from the login
signing_secret. - Policy-First: Authorization is always explicit. No access unless a policy grants it.
Getting Help
- Documentation: You're reading it! Check out the other sections in the sidebar.
- GitHub Issues: github.com/upside-down-research/code/issues
- CLI Help:
housectl <command> --helpfor any command
Ready to build something awesome? Let's go! 🚀