Tenant API
Table of Contents
upsquad/tenant/v1/security_config.proto
GetTenantSecurityConfigRequest
GetTenantSecurityConfigRequest is deliberately empty — tenant id is resolved from the authenticated context, never from the body.
GetTenantSecurityConfigResponse
GetTenantSecurityConfigResponse returns the current tenant config.
| Field | Type | Label | Description |
|---|---|---|---|
| config | TenantSecurityConfig | config is the current persisted tenant security config (or platform defaults when no row exists yet). |
TenantSecurityConfig
TenantSecurityConfig carries the editable surface for the security pipeline. Tenant id is NOT a field here — it is resolved from the authenticated context (defence against forged-body attacks).
| Field | Type | Label | Description |
|---|---|---|---|
| input_filter_mode | string | input_filter_mode controls the pattern-scanner severity for inbound prompts. L5 — posture-changing. | |
| output_filter_mode | string | output_filter_mode controls the pattern-scanner severity for agent outputs. L5 — posture-changing. | |
| redact_secrets | bool | redact_secrets enables server-side secret redaction in outputs. Turning this OFF is a posture-downgrade — L5 required. | |
| redact_pii | bool | redact_pii enables PII redaction in outputs. | |
| redact_system_prompt | bool | redact_system_prompt removes the system prompt from agent responses before the client sees them. | |
| schema_validation_mode | string | schema_validation_mode controls response-schema enforcement: log_only, warn, or block. L4 — tenant can tighten or relax their own enforcement within platform limits. | |
| tool_scan_enabled | bool | tool_scan_enabled toggles output scanning of tool results. L4 — tenant-scoped operational knob. | |
| tool_result_max_bytes | int32 | tool_result_max_bytes caps the size of tool outputs scanned. Operational knob; L4. | |
| updated_at | google.protobuf.Timestamp | updated_at — server-stamped; read-only on the surface. |
UpdateTenantSecurityConfigRequest
UpdateTenantSecurityConfigRequest carries the desired tenant config.
| Field | Type | Label | Description |
|---|---|---|---|
| config | TenantSecurityConfig | config is the desired tenant security config. All fields are validated; invalid values return InvalidArgument with a FieldViolation[]. |
UpdateTenantSecurityConfigResponse
UpdateTenantSecurityConfigResponse returns the persisted tenant config.
| Field | Type | Label | Description |
|---|---|---|---|
| config | TenantSecurityConfig | config is the persisted tenant security config after successful Update, including server-stamped updated_at. |
TenantSecurityConfigService
TenantSecurityConfigService exposes the per-tenant security pipeline knobs. Tenant scope is sourced from the authenticated context — NEVER from a request field.
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| GetTenantSecurityConfig | GetTenantSecurityConfigRequest | GetTenantSecurityConfigResponse | GetTenantSecurityConfig returns the tenant's current security configuration, or the platform defaults when no row exists. Read clearance L3 (tenant admin) lets an org admin inspect their own posture without being able to change it. |
| UpdateTenantSecurityConfig | UpdateTenantSecurityConfigRequest | UpdateTenantSecurityConfigResponse | UpdateTenantSecurityConfig replaces the tenant's configuration after validating every field. Emits one config.updated audit event with a field-level diff. L5 clearance required. |
upsquad/tenant/v1/tenant.proto
AssignCopilotRequest
AssignCopilotRequest links a user to a personal copilot agent.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. |
AssignCopilotResponse
AssignCopilotResponse returns the copilot assignment result.
| Field | Type | Label | Description |
|---|---|---|---|
| copilot_agent_id | string | copilot_agent_id is the UUID of the assigned copilot agent. | |
| created | bool | created is true if a new agent was created, false if already assigned. |
AssignRoleRequest
AssignRoleRequest changes a user's clearance level.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. | |
| new_clearance | int32 | new_clearance is the new clearance level (1-5). | |
| caller_user_id | string | caller_user_id is the UUID of the user performing the assignment (for clearance checks). |
AssignRoleResponse
AssignRoleResponse confirms the role change.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the updated user record. |
BulkImportMembersRequest
BulkImportMembersRequest imports a batch of users.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| caller_user_id | string | caller_user_id is the UUID of the caller (for clearance checks). | |
| format | string | format is the input format: "csv" or "json". | |
| payload | bytes | payload is the raw CSV or JSON data (max 500 rows). |
BulkImportMembersResponse
BulkImportMembersResponse returns the import results.
| Field | Type | Label | Description |
|---|---|---|---|
| total_rows | int32 | total_rows is the number of rows parsed from the payload. | |
| success_count | int32 | success_count is the number of successfully imported rows. | |
| error_count | int32 | error_count is the number of rows that failed. | |
| results | ImportRowResult | repeated | results is the per-row import result detail. |
ConfigureCopilotRequest
ConfigureCopilotRequest sets the copilot persona and/or model.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. | |
| persona | string | persona is the system persona for the copilot (empty = no change). | |
| model_id | string | model_id is the LLM model ID (empty = no change). |
ConfigureCopilotResponse
ConfigureCopilotResponse confirms the copilot configuration update.
| Field | Type | Label | Description |
|---|---|---|---|
| copilot_agent_id | string | copilot_agent_id is the UUID of the configured copilot agent. | |
| updated_at | google.protobuf.Timestamp | updated_at is the server-side timestamp of the update. |
CreateOrganizationRequest
CreateOrganizationRequest provisions a new tenant.
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | name is the display name for the organisation. | |
| admin_email | string | admin_email is the email of the founding admin user. | |
| admin_clerk_user_id | string | admin_clerk_user_id is the Clerk user ID for the admin. | |
| admin_display_name | string | admin_display_name is the display name of the admin user. |
CreateOrganizationResponse
CreateOrganizationResponse returns the provisioned org and admin IDs.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the created organisation. | |
| admin_user_id | string | admin_user_id is the UUID of the admin user record. | |
| default_pillar_id | string | default_pillar_id is the UUID of the auto-created default pillar. | |
| default_team_id | string | default_team_id is the UUID of the auto-created default team. | |
| subscription_id | string | subscription_id is the UUID of the free-trial subscription. |
DeployTeamFromSuggestionRequest
DeployTeamFromSuggestionRequest deploys a team structure from a suggestion.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| suggestion | TeamSuggestion | suggestion is the team structure to deploy. |
DeployTeamFromSuggestionResponse
DeployTeamFromSuggestionResponse returns the IDs of all created entities.
| Field | Type | Label | Description |
|---|---|---|---|
| pillar_ids | string | repeated | pillar_ids is the list of created pillar UUIDs. |
| team_ids | string | repeated | team_ids is the list of created team UUIDs. |
| agent_ids | string | repeated | agent_ids is the list of created agent UUIDs. |
DisableUserRequest
DisableUserRequest suspends a user (preserves data, blocks access).
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. | |
| caller_user_id | string | caller_user_id is the UUID of the user performing the action (for clearance checks). |
DisableUserResponse
DisableUserResponse returns the updated user record.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the updated user record with status 'suspended'. |
EnableUserRequest
EnableUserRequest activates a user (from suspended or invited).
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. | |
| caller_user_id | string | caller_user_id is the UUID of the user performing the action (for clearance checks). |
EnableUserResponse
EnableUserResponse returns the updated user record.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the updated user record with status 'active'. |
GetOrgHierarchyRequest
GetOrgHierarchyRequest is the input for the GetOrgHierarchy RPC.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. |
GetOrgHierarchyResponse
GetOrgHierarchyResponse is the output for the GetOrgHierarchy RPC.
| Field | Type | Label | Description |
|---|---|---|---|
| root | OrgHierarchyNode | root is the top-level organisation node with nested pillar and team children. |
GetOrganizationRequest
GetOrganizationRequest retrieves an organisation by ID.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. |
GetOrganizationResponse
GetOrganizationResponse returns the organisation record.
| Field | Type | Label | Description |
|---|---|---|---|
| organization | Organization | organization contains the full organisation record. |
GetTeamSuggestionRequest
GetTeamSuggestionRequest asks the AI to suggest a team structure.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. |
GetTeamSuggestionResponse
GetTeamSuggestionResponse returns the AI-generated team suggestion.
| Field | Type | Label | Description |
|---|---|---|---|
| suggestion_json | string | suggestion_json is a JSON-encoded team structure suggestion. |
GetUserProfileRequest
GetUserProfileRequest retrieves a full user profile including copilot.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user. |
GetUserProfileResponse
GetUserProfileResponse returns the user profile with copilot details.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the user record. | |
| copilot_agent_id | string | copilot_agent_id is the UUID of the assigned copilot agent (empty if none). | |
| copilot_persona | string | copilot_persona is the copilot's system persona (empty if no copilot). | |
| copilot_model_id | string | copilot_model_id is the copilot's LLM model ID (empty if no copilot). |
ImportRowResult
ImportRowResult describes the outcome of a single import row.
| Field | Type | Label | Description |
|---|---|---|---|
| row_number | int32 | row_number is the 1-based index of the row in the input. | |
| success | bool | success is true if the row was imported successfully. | |
| error | string | error is the error message (empty on success). | |
| user_id | string | user_id is the UUID of the created user (populated on success). |
InviteUserRequest
InviteUserRequest creates a new user invitation.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| string | email is the invitee's email address. | ||
| display_name | string | display_name is the invitee's display name. | |
| clearance | int32 | clearance is the target clearance level (1-5). | |
| pillar_id | string | pillar_id optionally assigns the user to a pillar. | |
| team_id | string | team_id optionally assigns the user to a team. | |
| caller_user_id | string | caller_user_id is the UUID of the user performing the invite (for clearance checks). |
InviteUserResponse
InviteUserResponse returns the invited user record.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the created user record with status 'invited'. |
ListUsersRequest
ListUsersRequest lists users in an organisation.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| status_filter | string | status_filter optionally filters by user status (empty = all non-deleted). | |
| page_size | int32 | page_size is the maximum number of results per page. Default 50, max 100. | |
| page_token | int32 | page_token is the offset for pagination (0-based). |
ListUsersResponse
ListUsersResponse returns the list of users.
| Field | Type | Label | Description |
|---|---|---|---|
| users | User | repeated | users is the list of user records. |
| total_count | int32 | total_count is the total number of matching users. |
MoveMemberRequest
MoveMemberRequest reassigns a user to a different pillar and/or team.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the target user to move. | |
| caller_user_id | string | caller_user_id is the UUID of the caller (for clearance checks). | |
| pillar_id | string | pillar_id is the new pillar UUID (empty = no change). | |
| team_id | string | team_id is the new team UUID (empty = no change). |
MoveMemberResponse
MoveMemberResponse returns the updated user.
| Field | Type | Label | Description |
|---|---|---|---|
| user | User | user contains the updated user record. |
OrgHierarchyNode
OrgHierarchyNode represents a single node in the organisation hierarchy tree. The node_type field indicates whether this is an org, pillar, or team node.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the UUID of the entity (org, pillar, or team). | |
| name | string | name is the display name of the entity. | |
| node_type | string | node_type is one of: org, pillar, team. | |
| children | OrgHierarchyNode | repeated | children is the list of child nodes (pillars under org, teams under pillar). |
Organization
Organization is the domain object for a tenant organisation.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the UUID primary key. | |
| name | string | name is the display name. | |
| onboarding_completed | bool | onboarding_completed indicates whether onboarding is done. | |
| created_at | google.protobuf.Timestamp | created_at is the creation timestamp. |
RemoveUserRequest
RemoveUserRequest soft-deletes a user.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| user_id | string | user_id is the UUID of the user to remove. | |
| caller_user_id | string | caller_user_id is the UUID of the user performing the removal (for clearance checks). |
RemoveUserResponse
RemoveUserResponse confirms user removal.
| Field | Type | Label | Description |
|---|---|---|---|
| removed_at | google.protobuf.Timestamp | removed_at is the server-side timestamp of the soft-delete. |
SubmitOnboardingQuestionnaireRequest
SubmitOnboardingQuestionnaireRequest persists the onboarding answers.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation. | |
| answers | string | answers is a JSON-encoded questionnaire response. |
SubmitOnboardingQuestionnaireResponse
SubmitOnboardingQuestionnaireResponse confirms the submission.
| Field | Type | Label | Description |
|---|---|---|---|
| ok | bool | ok is true when the questionnaire was saved successfully. |
SuggestedAgent
SuggestedAgent describes a single agent in a team suggestion.
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | name is the agent's display name. | |
| persona | string | persona is the agent's system persona prompt. | |
| clearance | int32 | clearance is the suggested clearance level. | |
| model_id | string | model_id is the suggested LLM model ID. |
SuggestedPillar
SuggestedPillar describes a pillar within a team suggestion.
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | name is the pillar's display name. | |
| teams | SuggestedTeam | repeated | teams is the list of teams for this pillar. |
SuggestedTeam
SuggestedTeam describes a team within a team suggestion.
| Field | Type | Label | Description |
|---|---|---|---|
| name | string | name is the team's display name. | |
| agents | SuggestedAgent | repeated | agents is the list of agents for this team. |
TeamSuggestion
TeamSuggestion is the top-level AI-generated team structure.
| Field | Type | Label | Description |
|---|---|---|---|
| pillars | SuggestedPillar | repeated | pillars is the list of suggested pillars. |
UpdateOrganizationRequest
UpdateOrganizationRequest patches mutable fields on an organisation.
| Field | Type | Label | Description |
|---|---|---|---|
| org_id | string | org_id is the UUID of the organisation to update. | |
| name | string | name is the new display name (empty string = no change). |
UpdateOrganizationResponse
UpdateOrganizationResponse returns the updated organisation.
| Field | Type | Label | Description |
|---|---|---|---|
| organization | Organization | organization contains the updated organisation record. |
User
User is the domain object for a human operator in the tenant.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the UUID primary key. | |
| org_id | string | org_id is the parent organisation UUID. | |
| clerk_user_id | string | clerk_user_id is the Clerk authentication user ID. | |
| string | email is the user's email address. | ||
| display_name | string | display_name is the user's display name. | |
| clearance | int32 | clearance is the user's clearance level (1-5). | |
| pillar_id | string | pillar_id is the assigned pillar UUID (empty if unassigned). | |
| team_id | string | team_id is the assigned team UUID (empty if unassigned). | |
| status | string | status is one of: active, invited, suspended, removed. | |
| created_at | google.protobuf.Timestamp | created_at is the creation timestamp. |
TenantService
TenantService manages organisations, users, and the AI team onboarding flow. Unit-hierarchy mutations (pillars / teams) moved to OrgUnitService in Wave K.1 (#693); this service no longer exposes Pillar/Team CRUD.
--- Organisation lifecycle ---
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| CreateOrganization | CreateOrganizationRequest | CreateOrganizationResponse | CreateOrganization provisions a new tenant with admin user, default pillar, default team, and a 14-day free-trial subscription in a single transaction. |
| GetOrganization | GetOrganizationRequest | GetOrganizationResponse | GetOrganization returns the organisation record for the given ID. |
| UpdateOrganization | UpdateOrganizationRequest | UpdateOrganizationResponse | UpdateOrganization patches mutable organisation fields (name, onboarding state). |
| GetOrgHierarchy | GetOrgHierarchyRequest | GetOrgHierarchyResponse | GetOrgHierarchy returns the full org hierarchy as a tree of pillars and teams. Read-only view composed server-side from the org_units mirror; unit CRUD lives on OrgUnitService. |
| InviteUser | InviteUserRequest | InviteUserResponse | InviteUser creates an invited user record. Caller clearance must be >= target. |
| ListUsers | ListUsersRequest | ListUsersResponse | ListUsers returns users in the organisation with optional status filter. |
| RemoveUser | RemoveUserRequest | RemoveUserResponse | RemoveUser soft-deletes a user (sets deleted_at). Caller clearance must be > target. |
| AssignRole | AssignRoleRequest | AssignRoleResponse | AssignRole changes a user's clearance level. Caller must have clearance >= new level AND > the user's current clearance. |
| EnableUser | EnableUserRequest | EnableUserResponse | EnableUser sets a user's status to active (from suspended or invited). Caller clearance must be > target clearance. |
| DisableUser | DisableUserRequest | DisableUserResponse | DisableUser sets a user's status to suspended (preserves data, blocks access). Caller clearance must be > target clearance. |
| AssignCopilot | AssignCopilotRequest | AssignCopilotResponse | AssignCopilot links a user to a personal copilot agent. Creates the agent if no copilot is assigned yet. Idempotent. |
| ConfigureCopilot | ConfigureCopilotRequest | ConfigureCopilotResponse | ConfigureCopilot sets the copilot's persona and/or model. Returns FailedPrecondition if no copilot is assigned. |
| GetUserProfile | GetUserProfileRequest | GetUserProfileResponse | GetUserProfile returns the full user record including copilot assignment. |
| SubmitOnboardingQuestionnaire | SubmitOnboardingQuestionnaireRequest | SubmitOnboardingQuestionnaireResponse | SubmitOnboardingQuestionnaire persists the questionnaire answers on the org. |
| GetTeamSuggestion | GetTeamSuggestionRequest | GetTeamSuggestionResponse | GetTeamSuggestion calls the Context Engine's AssembleContext with an onboarding persona and the questionnaire answers to produce a suggested AI team structure. |
| DeployTeamFromSuggestion | DeployTeamFromSuggestionRequest | DeployTeamFromSuggestionResponse | DeployTeamFromSuggestion provisions pillars, teams, agents, and configurations from a previously generated suggestion in a single transaction. |
| MoveMember | MoveMemberRequest | MoveMemberResponse | MoveMember reassigns a user to a different pillar and/or team. Caller clearance must be >= target user's clearance. |
| BulkImportMembers | BulkImportMembersRequest | BulkImportMembersResponse | BulkImportMembers imports a batch of users (up to 500 rows) in a single transaction, returning per-row success/error results. |
Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|---|---|---|---|---|---|---|---|---|
| double | double | double | float | float64 | double | float | Float | |
| float | float | float | float | float32 | float | float | Float | |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |