CheckAuthorizationRequest evaluates if an action is allowed
This is the core authorization check that evaluates policies against a request. The request context is a map of string key-value pairs that describe the authorization request.
The "object" value MUST be a valid hc:// URI where the domain UUID is used to identify which domain's policies apply. The domain UUID must exist and be accessible by the tenant in the JWT token.
You can include any additional context attributes that your policies need:
{ "context": { "subject": "user:alice@example.com", "action": "read", "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf", "time": "2024-01-15T10:30:00Z", "ip_address": "192.168.1.100", "owner": "user:alice@example.com" } }
This would match a policy like: { "engine": EVALUATION_ENGINE_PREFIX, "statements": [{ "rules": { "action": "read", "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/" } }] }
If policies contain macros (e.g., $current_user()), they are evaluated using information from:
For example, a policy with: {"subject": "$current_user()", "owner": "$resource_owner()"} Would expand at evaluation time to: {"subject": "user:alice@example.com", "owner": "user:alice@example.com"} And match if both values are equal.
Returns gRPC error if:
| Field | Type | Label | Description |
|---|---|---|---|
| context | CheckAuthorizationRequest.ContextEntry | repeated | Authorization context (key-value pairs, supporting multi-valued attributes) REQUIRED keys: - subject: Entity performing the action - action: Operation being attempted - object: Resource in hc:// URI format OPTIONAL keys: - Any custom attributes your policies need (time, ip_address, owner, etc.) MULTI-VALUE SUPPORT: Each value can be either a single string or an array of strings. Multi-valued attributes use OR semantics during policy matching: A request with group: ["red", "blue"] will match policy statement group: "blue" Example with single values: { "subject": {"single": "user:alice@example.com"}, "action": {"single": "read"}, "object": {"single": "hc://550e8400.../documents/report.pdf"} } Example with multi-valued attribute: { "subject": {"single": "user:alice@example.com"}, "action": {"single": "read"}, "object": {"single": "hc://550e8400.../documents/report.pdf"}, "group": {"multiple": {"values": ["red", "blue", "green"]}} } | |
| Field | Type | Label | Description |
|---|---|---|---|
| key | string | ||
| value | RequestValue |
CheckAuthorizationResponse returns the authorization decision
The authorized field indicates whether the request should be allowed.
authorized = true:
authorized = false:
After receiving the response, your application should:
All CheckAuthorization calls should be logged to the audit service with:
| Field | Type | Label | Description |
|---|---|---|---|
| authorized | bool | True if the action is allowed, false if denied or no policy matched This is the authorization decision. Application MUST enforce this result. | |
ClearUserAttributesRequest removes all attributes for a user in the current tenant
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to clear attributes for |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to create key for |
| Field | Type | Label | Description |
|---|---|---|---|
| api_key | string | JWT token that can be used for API authentication |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant that will own the domain | |
| name | string | Domain name, must be unique within tenant | |
| superior_domain_ids | string | repeated | UUIDs - Parent domains for hierarchy |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User the token is for | |
| string | Email address to verify | ||
| token_type | TokenType | Type of verification token | |
| expiration_hours | uint32 | Token validity period (default 24) |
| Field | Type | Label | Description |
|---|---|---|---|
| token | string | Generated verification token (64-char alphanumeric) | |
| expires_at | google.protobuf.Timestamp | Token expiration timestamp |
| Field | Type | Label | Description |
|---|---|---|---|
| username | string | Username for the new user | |
| string | Email address | ||
| oauth_provider | string | OAuth provider (e.g., "google") | |
| oauth_subject | string | Provider's unique user identifier | |
| email_verified | bool | Whether email is pre-verified by OAuth provider | |
| tenant_id | string | optional | Optional tenant to associate user with |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - Created user's identifier |
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | Service account name (will be prefixed with svc:) | |
| description | string | Human-readable description | |
| tenant_id | string | UUID - Tenant to associate with | |
| expiration_days | uint64 | optional | API key expiration (default: 365 days) |
| Field | Type | Label | Description |
|---|---|---|---|
| service_account_id | string | UUID - Created service account ID | |
| username | string | Full username (svc:name) | |
| api_key_id | string | UUID - API key ID | |
| string | Generated email (name@service.internal) | ||
| expiration | int64 | Unix epoch when API key expires | |
| token | string | JWT token for immediate authentication (same as Login) |
Request to create a new tenant. See CreateTenant RPC documentation for details on the bootstrap behavior that occurs when a tenant is created (automatic domain, policies, and user association).
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | Tenant name, must be globally unique across the system. Used for human-readable identification and lookup via GetTenantByName. | |
| description | string | Human-readable description of the tenant's purpose or organization. |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant to grant access to | |
| user_id | string | UUID - User to grant access |
| Field | Type | Label | Description |
|---|---|---|---|
| username | string | Must be unique, used for login | |
| string | Must be valid email format | ||
| password | string | Must meet security requirements |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - Created user's identifier |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User who owns the key | |
| key_id | string | UUID - Key to delete |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant ID for access control | |
| domain_id | string | UUID - Domain to delete |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Service account ID to delete |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Tenant to delete |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant to revoke access from | |
| user_id | string | UUID - User to revoke access |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - User to delete |
Domain represents a policy container within a tenant Domains can be hierarchical through superior_domain_ids
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Unique domain identifier | |
| name | string | Domain name, unique within tenant | |
| tenant_id | string | UUID - Owning tenant | |
| active | bool | Whether domain is active for policy evaluation | |
| superior_domain_ids | string | repeated | UUIDs - Parent domains in hierarchy |
| policies | Policy | repeated | Policies attached to this domain |
| Field | Type | Label | Description |
|---|---|---|---|
| oauth_provider | string | OAuth provider (e.g., "google") | |
| oauth_subject | string | Provider's unique user identifier |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User ID if found | |
| found | bool | True if user exists | |
| username | string | Username if found | |
| string | Email if found |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User who owns the key | |
| key_id | string | UUID - Specific key to retrieve |
| Field | Type | Label | Description |
|---|---|---|---|
| api_key | string | JWT token (metadata only, not the secret) |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant ID for access control | |
| name | string | Domain name to look up |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant ID for access control | |
| domain_id | string | UUID - Domain whose policies to retrieve |
| Field | Type | Label | Description |
|---|---|---|---|
| policies | Policy | repeated | All policies attached to the domain |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant ID for access control | |
| domain_id | string | UUID - Domain to retrieve |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Service account ID |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant to get associations for |
| Field | Type | Label | Description |
|---|---|---|---|
| users | User | repeated | All users associated with the tenant |
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | Tenant name to look up |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Tenant identifier |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant to check | |
| user_id | string | UUID - User to check |
| Field | Type | Label | Description |
|---|---|---|---|
| is_associated | bool | True if user can act on behalf of tenant |
GetUserAttributesRequest retrieves all attributes for a user in the current tenant
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to get attributes for |
GetUserAttributesResponse returns all attributes grouped by key
| Field | Type | Label | Description |
|---|---|---|---|
| attributes | GetUserAttributesResponse.AttributesEntry | repeated | All attributes for the user |
| Field | Type | Label | Description |
|---|---|---|---|
| key | string | ||
| value | StringArray |
| Field | Type | Label | Description |
|---|---|---|---|
| username | string | Username to look up |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - User to retrieve |
JWT will be passed in request headers No body needed - authentication via Bearer token
| Field | Type | Label | Description |
|---|---|---|---|
| is_logged_in | bool | True if JWT is valid and session active |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant to list accounts for | |
| active_only | bool | optional | Filter to only active accounts (default: false) |
| Field | Type | Label | Description |
|---|---|---|---|
| service_accounts | ServiceAccount | repeated | |
| total_count | uint32 | Total number of service accounts |
Empty for now, could add pagination later
| Field | Type | Label | Description |
|---|---|---|---|
| tenants | Tenant | repeated | All tenants in the system |
Empty for now, could add pagination later
| Field | Type | Label | Description |
|---|---|---|---|
| users | User | repeated | All users in the system |
| Field | Type | Label | Description |
|---|---|---|---|
| username | string | Username credential | |
| password | string | Password credential | |
| tenant | string | optional | Tenant name - for multi-tenant login |
| duration | uint64 | optional | Token validity duration in seconds |
| Field | Type | Label | Description |
|---|---|---|---|
| token | string | JWT token for subsequent API calls | |
| user_id | string | UUID - Logged in user | |
| tenant_id | string | optional | UUID - Tenant context for the session |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - Must match JWT claims |
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to mark as verified |
Policy defines authorization rules for resources
A policy is a named set of rules that determine whether a request should be allowed or denied. Policies are attached to domains and evaluated during CheckAuthorization calls.
During CheckAuthorization, each policy is evaluated as follows:
invert: Reverses the match result
deny: Makes this a deny policy (overrides allows)
Allow read access to documents: { "name": "read-documents", "description": "Allow users to read documents", "invert": false, "deny": false, "engine": EVALUATION_ENGINE_PREFIX, "statements": [{ "rules": { "action": "read", "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/" } }] }
Deny access to sensitive resources: { "name": "deny-sensitive", "description": "Prevent access to sensitive resources", "invert": false, "deny": true, "engine": EVALUATION_ENGINE_PREFIX, "statements": [{ "rules": { "object": "hc://550e8400-e29b-41d4-a716-446655440000/sensitive/" } }] }
Allow owner-only access using macros: { "name": "owner-access", "description": "Users can only access resources they own", "invert": false, "deny": false, "engine": EVALUATION_ENGINE_FIXED, "statements": [{ "rules": { "subject": "$current_user()", "owner": "$resource_owner()" } }] }
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | Policy name for identification Must be unique within a domain Used for debugging and audit trails | |
| description | string | Human-readable description Explain the policy's purpose and when it applies Recommended for all policies | |
| invert | bool | Invert the match result false (default): If statements match, apply allow/deny true: If statements match, do NOT apply (implement "except" logic) | |
| deny | bool | Whether this is a deny policy false (default): This is an allow policy true: This is a deny policy (overrides all allow policies) | |
| engine | EvaluationEngine | Evaluation engine for matching rules Determines how statement rules are matched against request context | |
| statements | PolicyStatement | repeated | Policy statements (rules) A policy matches if ANY statement matches Use multiple statements for OR logic (e.g., allow read OR write) |
PolicyStatement contains the actual rules to evaluate
A statement is a set of key-value pairs that must ALL match the request context for the statement to match (AND logic).
For a statement to match:
Policy statement: { "rules": { "action": "read", "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/" } }
Request context (matches): { "subject": "user:alice@example.com", // ignored (not in rules) "action": "read", // matches "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf" // matches (PREFIX engine) }
Request context (does NOT match): { "action": "write", // does not match (not "read") "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf" }
Use multiple statements in a policy for OR logic: { "statements": [ {"rules": {"action": "read"}}, {"rules": {"action": "write"}} ] } This matches requests with action="read" OR action="write"
| Field | Type | Label | Description |
|---|---|---|---|
| rules | PolicyStatement.RulesEntry | repeated | Engine-specific rule definitions Keys: Arbitrary context attributes (subject, action, object, time, etc.) Values: Patterns to match (exact, prefix, regex, glob depending on engine) Common context keys: - subject: The entity performing the action - action: The operation (read, write, delete, etc.) - object: The resource (hc:// URI) - time: Request timestamp - ip_address: Client IP - user_agent: Client user agent - custom_key: Any application-specific attribute | |
| Field | Type | Label | Description |
|---|---|---|---|
| key | string | ||
| value | string |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Tenant ID for access control | |
| domain_id | string | UUID - Domain to update policies for | |
| policies | Policy | repeated | Complete policy set (replaces existing) |
RefreshLoginWithTenantRequest transmutes a tenantless login to a tenantful one
Returns LoginResponse with new JWT containing:
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID or name of tenant to associate the session with User must already be associated with this tenant |
Empty - refreshes tokens for all tenants
RemoveUserAttributeRequest removes attribute values for a user in the current tenant
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to remove attributes from | |
| attribute_key | string | Attribute key to modify | |
| attribute_values | string | repeated | Specific values to remove (empty = remove all for key) |
RequestValue supports both single and multi-valued context attributes Used in CheckAuthorizationRequest for multi-valued attribute matching
| Field | Type | Label | Description |
|---|---|---|---|
| single | string | Single string value | |
| multiple | StringArray | Multiple values (OR semantics in matching) |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Service account ID | |
| username | string | Full username (svc:name) | |
| string | Generated email (name@service.internal) | ||
| tenant_id | string | UUID - Tenant this account is homed to | |
| description | string | Human-readable description | |
| active | bool | Whether account is enabled | |
| created_at | int64 | Unix epoch | |
| api_key_id | string | UUID - Current API key ID | |
| api_key_expiration | int64 | Unix epoch when API key expires | |
| api_key_active | bool | Whether API key is currently valid |
SetUserAttributeRequest adds attribute values for a user in the current tenant
| Field | Type | Label | Description |
|---|---|---|---|
| user_id | string | UUID - User to set attributes for | |
| attribute_key | string | Attribute key (e.g., "group", "role") | |
| attribute_values | string | repeated | Values to add (e.g., ["red", "blue"]) |
| Field | Type | Label | Description |
|---|---|---|---|
| state | string | Random state string for CSRF protection | |
| tenant_id | string | optional | Optional tenant ID for the OAuth flow |
| expires_in_minutes | int32 | Expiration time in minutes (default 10) | |
| redirect_uri | string | Optional redirect URI after OAuth completion | |
| nonce | string | Optional nonce for additional security |
StringArray holds multiple string values for a single key
| Field | Type | Label | Description |
|---|---|---|---|
| values | string | repeated |
Tenant represents a top-level organizational unit All resources are isolated by tenant
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Unique tenant identifier | |
| name | string | Tenant name, globally unique | |
| description | string | Human-readable description | |
| active | bool | Whether tenant is active | |
| control_plane | Tokens | API call limits for management operations | |
| data_plane | Tokens | API call limits for authorization operations | |
| last_token_reset | google.protobuf.Timestamp | Last token refresh time | |
| subscription | string | Subscription plan identifier | |
| domains | Domain | repeated | Domains owned by this tenant |
API call tracking for rate limiting
Housecarl uses a token bucket algorithm for rate limiting based on API calls. Each operation consumes one call, and the call quota is replenished during RefreshTenants operations. "Calls" represents the most technically accurate and user-controllable measure of system usage.
When an operation is performed:
Call RefreshTenants periodically (e.g., hourly, daily) to reset:
Tenants have two separate call quotas:
Users have a separate quota:
max_overage allows temporary bursts above max_calls. This is useful for handling traffic spikes without immediately rejecting requests.
Example: max_calls=1000, max_overage=500
| Field | Type | Label | Description |
|---|---|---|---|
| max_tokens | int64 | Maximum calls available per refresh cycle This is your baseline rate limit quota | |
| tokens | int64 | Current available calls (decremented on each operation) When this reaches 0, overage is used | |
| max_overage | int64 | Maximum allowed overage (burst capacity above max_calls) Set to 0 to disable burst capacity | |
| overage | int64 | Current overage usage (incremented when calls reach 0) Reset to 0 during RefreshTenants |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant_id | string | UUID - Must match domain's tenant_id | |
| domain | Domain | Updated domain object |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Service account ID | |
| description | string | optional | New description (if provided) |
| active | bool | optional | New active status (if provided) |
| Field | Type | Label | Description |
|---|---|---|---|
| tenant | Tenant | Updated tenant object, ID must match existing tenant |
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - User to update | |
| username | string | New username (must be unique) | |
| string | New email | ||
| password | string | optional | New password (optional) |
| active | bool | Active status |
User represents an authenticated entity that can access tenants
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | UUID - Unique user identifier | |
| username | string | Unique username for login | |
| string | Email address | ||
| active | bool | Whether user can login | |
| api_key_ids | string | repeated | UUIDs - Associated API keys |
| user_plane | Tokens | User-specific API call limits | |
| email_verified | bool | Whether email has been verified |
| Field | Type | Label | Description |
|---|---|---|---|
| token | string | Token to validate | |
| token_type | TokenType | Expected token type |
| Field | Type | Label | Description |
|---|---|---|---|
| valid | bool | True if token is valid | |
| user_id | string | UUID - User ID associated with token | |
| string | Email address associated with token | ||
| error_message | string | Error description if invalid (expired, used, not found, etc.) |
| Field | Type | Label | Description |
|---|---|---|---|
| state | string | State string to validate |
| Field | Type | Label | Description |
|---|---|---|---|
| valid | bool | True if state is valid and not expired | |
| tenant_id | string | Associated tenant ID | |
| redirect_uri | string | Associated redirect URI (if any) | |
| nonce | string | Associated nonce (if any) | |
| error_message | string | Error description if invalid |
Policy evaluation engine types
The evaluation engine determines how policy statement rules are matched against the request context during authorization checks.
All engines operate on key-value pairs where both keys and values are strings. The request context is matched against policy statement rules according to the selected engine's matching semantics.
For a policy statement to match:
EXAMPLE REQUEST CONTEXT: { "subject": "user:alice@example.com", "action": "read", "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf", "time": "2024-01-15T10:30:00Z", "ip_address": "192.168.1.100" }
| Name | Number | Description |
|---|---|---|
| EVALUATION_ENGINE_UNSPECIFIED | 0 | Unspecified engine - do not use in production policies |
| EVALUATION_ENGINE_FIXED | 1 | FIXED: Exact string match (case-sensitive) Policy statement values must exactly match request context values. Use for: Precise matching of known values Example policy statement: { "subject": "user:alice@example.com", "action": "read" } Matches request context with: subject = "user:alice@example.com" (exact match) action = "read" (exact match) Does NOT match: subject = "user:alice" (not exact) action = "READ" (case-sensitive) | |
| EVALUATION_ENGINE_PREFIX | 2 | PREFIX: Prefix matching (starts with) Request context values must start with policy statement values. Use for: Hierarchical resource paths, user groups, action categories Example policy statement: { "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/", "action": "read" } Matches request context with: object = "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf" object = "hc://550e8400-e29b-41d4-a716-446655440000/documents/folder/file.txt" Does NOT match: object = "hc://550e8400-e29b-41d4-a716-446655440000/images/photo.jpg" | |
| EVALUATION_ENGINE_REGEX | 3 | REGEX: Regular expression matching Policy statement values are regular expressions matched against request context values using Rust regex syntax. Use for: Complex pattern matching, wildcard domains, time ranges Example policy statement: { "subject": "^user:[a-z]+@example\.com$", "action": "read|write", "time": "^2024-.T(09|10|11|12|13|14|15|16):." } Matches request context with: subject = "user:alice@example.com" (matches regex) action = "write" (matches alternation) time = "2024-01-15T14:30:00Z" (matches time range) WARNING: Complex regex can impact performance. Use PREFIX or GLOB when simpler matching suffices. | |
| EVALUATION_ENGINE_GLOB | 4 | GLOB: Glob pattern matching (shell-style wildcards) Policy statement values use glob patterns (* for any characters, ? for single character) matched against request context values. Use for: Filename patterns, simple wildcards Example policy statement: { "object": "hc://550e8400-e29b-41d4-a716-446655440000/documents/.pdf", "subject": "user:@example.com" } Matches request context with: object = "hc://550e8400-e29b-41d4-a716-446655440000/documents/report.pdf" subject = "user:alice@example.com" Does NOT match: object = "hc://550e8400-e29b-41d4-a716-446655440000/documents/folder/file.pdf" (glob * does not match path separators by default) | |
| EVALUATION_ENGINE_FIRST_ORDER_LOGIC | 5 | FIRST_ORDER_LOGIC: Complex logical expressions Reserved for future use. Supports complex boolean logic, comparisons, and quantifiers. NOT CURRENTLY IMPLEMENTED | |
| Name | Number | Description |
|---|---|---|
| TOKEN_TYPE_UNSPECIFIED | 0 | |
| TOKEN_TYPE_EMAIL_VERIFICATION | 1 | |
| TOKEN_TYPE_PASSWORD_RESET | 2 | |
| TOKEN_TYPE_EMAIL_CHANGE | 3 |
Domain operations Domains are hierarchical policy containers within a tenant
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| CreateDomain | CreateDomainRequest | Domain | Creates a new domain for the specified tenant Domain names must be unique within a tenant and can have superior domains for hierarchy |
| GetDomain | GetDomainRequest | Domain | Retrieves a domain for the specified tenant Returns error if domain doesn't exist or belongs to different tenant |
| GetDomainByName | GetDomainByNameRequest | Domain | Retrieves a domain by name for the specified tenant Returns error if domain doesn't exist or is not unique |
| UpdateDomain | UpdateDomainRequest | .google.protobuf.Empty | Updates an existing domain for the specified tenant ID and tenant_id in request body must match URL parameters |
| DeleteDomain | DeleteDomainRequest | .google.protobuf.Empty | Deletes the specified domain Will fail if domain has dependent resources |
| GetDomainPolicies | GetDomainPoliciesRequest | GetDomainPoliciesResponse | Retrieves policies for the specified domain Returns the policy list attached to the domain |
| PutDomainPolicies | PutDomainPoliciesRequest | .google.protobuf.Empty | Updates policies for the specified domain Replaces the entire policy set for the domain |
| CreateTenant | CreateTenantRequest | Tenant | Creates a new tenant with automatic bootstrap configuration. BOOTSTRAP BEHAVIOR: This operation is a bootstrap operation that any authenticated user can perform. No policy-based authorization check is required beyond valid authentication. When a tenant is created, the following resources are automatically provisioned in a single atomic transaction: 1. TENANT: The tenant record is created with the provided name and description. 2. USER ASSOCIATION: The creating user is automatically associated with the new tenant via a tenant-user link. This allows the user to operate within the tenant context. 3. ROOT DOMAIN: A domain named "root" is created as the tenant's primary domain. This domain cannot be renamed (enforced by database trigger) and serves as the default policy evaluation context for the tenant. 4. STARTER POLICIES: Two policies are automatically created in the root domain: a) "starter" policy - Grants the creating user full access to all resources within the tenant. This policy matches: - subject (sub claim): the creating user's UUID - action: any (.+) - object: any housecarl resource (hc://.+) b) "root access" policy - Grants the system root user (from the root tenant) administrative access to this tenant. This enables platform-level administration and support operations. SECURITY CONSIDERATIONS: - The starter policy uses the user's UUID, not username, preventing policy bypass through username changes. - Additional users can be granted access by creating new policies in the root domain or by associating them with the tenant and adding appropriate policy statements. - The creating user should configure appropriate policies before inviting other users to the tenant. Returns: The created Tenant object with its assigned UUID. | |
| GetTenant | GetTenantRequest | Tenant | Retrieves the specified tenant by ID |
| GetTenantByName | GetTenantByNameRequest | Tenant | Gets a tenant by name Tenant names are unique across the system |
| UpdateTenant | UpdateTenantRequest | .google.protobuf.Empty | Updates an existing tenant ID in request body must match the tenant being updated |
| DeleteTenant | DeleteTenantRequest | .google.protobuf.Empty | Deletes the specified tenant Will cascade delete associated resources |
| ListTenants | ListTenantsRequest | ListTenantsResponse | Gets all tenants Admin operation that returns all tenants in the system |
| RefreshTenants | RefreshTenantsRequest | .google.protobuf.Empty | Refreshes call quotas for all tenants Should be called every refresh cycle to reset API call limits Updates control_plane, data_plane call quotas, and resets overage counters |
| CreateUser | CreateUserRequest | CreateUserResponse | Creates a new user Can be called without authentication Username and email must be unique, password must meet security requirements |
| GetUser | GetUserRequest | User | Get user by ID |
| GetUserByName | GetUserByNameRequest | User | Get user by name Username lookup across the system |
| UpdateUser | UpdateUserRequest | User | Updates an existing user Can update email, active status, and other metadata |
| DeleteUser | DeleteUserRequest | .google.protobuf.Empty | Deletes the specified user Will remove all tenant associations and invalidate tokens |
| ListUsers | ListUsersRequest | ListUsersResponse | Get all users Admin operation that returns all users in the system |
| Login | LoginRequest | LoginResponse | Log in a user Returns JWT token for subsequent API calls Optional tenant parameter for multi-tenant login |
| Logout | LogoutRequest | .google.protobuf.Empty | Log out a user Invalidates the current JWT token User can only logout their own session |
| IsLoggedIn | IsLoggedInRequest | IsLoggedInResponse | Check if a user is logged in Validates JWT token and checks if user session is still active |
| RefreshLoginWithTenant | RefreshLoginWithTenantRequest | LoginResponse | Refresh login with tenant context Transmutes a tenantless login session to a tenantful one Validates current JWT has no tenant, then issues new JWT with tenant_id SECURITY: Verifies user is associated with requested tenant before issuing new token |
| CreateApiKey | CreateApiKeyRequest | CreateApiKeyResponse | Creates an API key for the user, associated to the logged-in tenant API keys allow programmatic access without password authentication |
| GetApiKey | GetApiKeyRequest | GetApiKeyResponse | Gets the API key metadata for the user Returns key information but not the key value itself |
| DeleteApiKey | DeleteApiKeyRequest | .google.protobuf.Empty | Deletes the API key for the user Immediately invalidates the key |
| CreateServiceAccount | CreateServiceAccountRequest | CreateServiceAccountResponse | Creates a service account within a tenant Admin operation that provisions account + API key Returns API key secret (only shown once!) |
| ListServiceAccounts | ListServiceAccountsRequest | ListServiceAccountsResponse | Lists all service accounts in a tenant Admin operation |
| GetServiceAccount | GetServiceAccountRequest | ServiceAccount | Gets a specific service account by ID Admin operation |
| UpdateServiceAccount | UpdateServiceAccountRequest | .google.protobuf.Empty | Updates a service account (description, active status) Admin operation Cannot update username, email, or tenant_id |
| DeleteServiceAccount | DeleteServiceAccountRequest | .google.protobuf.Empty | Deletes a service account Admin operation Cascades to delete associated API keys |
| SetUserAttribute | SetUserAttributeRequest | .google.protobuf.Empty | Set attribute values for a user in the current tenant Adds the specified values to the user's attributes (upsert semantics) Existing values for the key are preserved; new values are added |
| RemoveUserAttribute | RemoveUserAttributeRequest | .google.protobuf.Empty | Remove attribute values from a user in the current tenant If attribute_values is empty, removes ALL values for the key If specific values provided, removes only those values |
| GetUserAttributes | GetUserAttributesRequest | GetUserAttributesResponse | Get all attributes for a user in the current tenant Returns attributes grouped by key with all values per key |
| ClearUserAttributes | ClearUserAttributesRequest | .google.protobuf.Empty | Clear all attributes for a user in the current tenant Removes every attribute key-value pair for the user |
| CheckAuthorization | CheckAuthorizationRequest | CheckAuthorizationResponse | Checks to see if the action is allowed Evaluates request against tenant's policy domains Request must contain "subject", "action", and "object" in context Object is a Resource that follows hc:// URI format |
| GetTenantAssociations | GetTenantAssociationsRequest | GetTenantAssociationsResponse | Get users associated with tenant Returns all users that have been granted access to the tenant |
| GetTenantUserAssociation | GetTenantUserAssociationRequest | GetTenantUserAssociationResponse | Get if tenant is associated for the specified user Returns true if user can act on behalf of the tenant |
| CreateTenantUserAssociation | CreateTenantUserAssociationRequest | .google.protobuf.Empty | Sets tenant to be associated for the specified user Grants user permission to act on behalf of the tenant |
| DeleteTenantUserAssociation | DeleteTenantUserAssociationRequest | .google.protobuf.Empty | Deletes tenant - user association Revokes user's permission to act on behalf of the tenant |
| CreateEmailVerificationToken | CreateEmailVerificationTokenRequest | CreateEmailVerificationTokenResponse | Creates an email verification token for the specified user Token is valid for the configured expiration period (default 24 hours) Automatically invalidates any existing unused tokens of the same type |
| ValidateEmailVerificationToken | ValidateEmailVerificationTokenRequest | ValidateEmailVerificationTokenResponse | Validates an email verification token Checks expiration, usage status, and token type Marks token as used upon successful validation |
| MarkEmailVerified | MarkEmailVerifiedRequest | .google.protobuf.Empty | Marks a user's email as verified Called after successful token validation during email verification flow |
| FindUserByOAuth | FindUserByOAuthRequest | FindUserByOAuthResponse | Finds a user by OAuth provider and subject ID Returns user information if found, error if not found |
| CreateOAuthUser | CreateOAuthUserRequest | CreateOAuthUserResponse | Creates a new user with OAuth credentials Associates user with specified tenant and marks email as verified |
| StoreOAuthState | StoreOAuthStateRequest | .google.protobuf.Empty | Stores OAuth state for CSRF protection during authorization flow State expires after configured period (default 10 minutes) |
| ValidateOAuthState | ValidateOAuthStateRequest | ValidateOAuthStateResponse | Validates OAuth state and retrieves associated information Checks expiration and marks state as used |
| Field | Type | Label | Description |
|---|---|---|---|
| service | string |
| Field | Type | Label | Description |
|---|---|---|---|
| status | HealthCheckResponse.ServingStatus |
| Name | Number | Description |
|---|---|---|
| UNKNOWN | 0 | |
| SERVING | 1 | |
| NOT_SERVING | 2 | |
| SERVICE_UNKNOWN | 3 | Used only by the Watch method. |
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| Check | HealthCheckRequest | HealthCheckResponse | |
| Watch | HealthCheckRequest | HealthCheckResponse stream |
Request to get JWT public key
Empty request - the public key is the same for all callers
Response containing JWT public key information
| Field | Type | Label | Description |
|---|---|---|---|
| public_key_bytes | bytes | Ed25519 public key bytes | |
| algorithm | string | Algorithm type (e.g., "Ed25519") | |
| key_id | string | Optional key identifier for key rotation |
JWT key management service for external service integration Provides public key distribution for JWT token verification
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| GetPublicKey | GetPublicKeyRequest | GetPublicKeyResponse | Gets the public key for JWT verification External services use this to verify JWT tokens issued by Housecarl |