PRE-RELEASE INFORMATION: SUBJECT TO CHANGE

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 housecarl.cloud and sign up. You have two options:

Email Signup

  1. Click "Sign up with Email"
  2. Enter your email address and create a password
  3. Check your email for verification link
  4. Click the link to verify your account
  5. Choose a name for your organization (this creates your tenant)

Google OAuth

  1. Click "Sign up with Google"
  2. Select your Google account
  3. 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://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 group attribute is "engineering"
    • AND they're trying to "read"
    • AND the resource starts with "hc://domain//documents/project-alpha/"
    • THEN allow the request

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:

  1. Signed up for Housecarl and got a tenant
  2. Installed and configured housectl
  3. Created an authorization policy using glob patterns
  4. 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

Administration

Developer Integration

Deep Dives

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:

  1. Is your policy actually deployed? housectl domain list-policies root
  2. Does the request exactly match the policy? Pattern matching is precise.
  3. Is the user associated with the tenant? housectl tenant is-user-associated your-org-name alice
  4. 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

Ready to build something awesome? Let's go! 🚀