Identity, licences & landing
Sign-in, sessions, two-factor enrolment, service-account keys, licence validation and the
landing dashboard. IdentityService is where every client starts: Login is one of only two
RPCs on the whole API that take no bearer token (the other is
ActivationService/ValidateLicense). See the API overview
for how the token is carried.
Summary
| Service | RPC | Kind | Purpose |
|---|---|---|---|
| IdentityService | Login | Unary | Exchange credentials, a TOTP code or an OIDC ID token for a session token |
| IdentityService | Logout | Unary | End every session of the calling account |
| IdentityService | EnrollTotp | Unary | Generate a TOTP secret to enrol |
| IdentityService | ConfirmTotp | Unary | Prove the authenticator works and turn two-factor on |
| IdentityService | UpdateUser | Unary | Change an account’s email, role or password |
| IdentityService | CreateInstance | Unary | Acknowledge an instance request (provisions nothing) |
| IdentityService | ListInstances | Unary | Deprecated. Instances the caller may use |
| IdentityService | GenerateServiceAccountKey | Unary | Mint a service-account token for the caller’s tenant |
| ActivationService | GenerateLicense | Unary | Not implemented: licences are issued offline |
| ActivationService | ValidateLicense | Unary | Check a signed licence key |
| ActivationService | ActivateLicense | Unary | Not implemented |
| LandingService | GetSystemStatus | Unary | Landing summary (currently always empty) |
| LandingService | GetDashboardStats | Unary | Live dashboard counters for the caller’s instance |
IdentityService
Full name semantics.v1.IdentityService.
This service handles authentication and account management for one FACE deployment. Membership
and roles of an instance are managed through the platform’s shared Admin page. They are not
managed here: the RegisterUser and DeleteUser RPCs were removed from this service.
Login
rpc Login(LoginRequest) returns (LoginResponse);- Kind: Unary.
- Auth: None. This RPC is exempt from bearer authentication.
- Errors:
INTERNALif the server cannot issue a session or start the MFA step, or cannot provision the local account for a first-time SSO user. An ordinary sign-in failure is not a gRPC error. The call succeeds withstatus: STATUS_FAILUREand a human-readablemessage.
Login is a one-step or two-step exchange, selected by method:
method | Required fields | Outcome |
|---|---|---|
AUTH_METHOD_CREDENTIALS | username (the account email), password; hcaptcha_token when the deployment enforces a captcha | STATUS_SUCCESS with token, or STATUS_MFA_REQUIRED with mfa_session if the account has TOTP enabled |
AUTH_METHOD_MFA_VERIFY | mfa_session (from the previous response), mfa_code (6-digit TOTP) | STATUS_SUCCESS with token |
AUTH_METHOD_GOOGLE_OIDC | oidc_token (an OIDC ID token from the deployment’s configured issuer) | STATUS_SUCCESS with token |
Behaviour worth knowing:
- Session lifetime. A session token is valid for 12 hours unless it is revoked first. Revocation (logout, or an admin changing the account) takes effect on every replica.
- MFA window. The
mfa_sessionfrom aSTATUS_MFA_REQUIREDresponse expires after 5 minutes. After that the MFA step fails with “MFA session expired” and the client must sign in again. - SSO-only deployments. A deployment can be locked to SSO. Password sign-in then fails with “Password sign-in is disabled”, except for the operator’s break-glass administrator.
- OIDC. The ID token must verify against the configured issuer and carry a verified email. That email must also be on the deployment’s allowlist. If SSO is configured and the allowlist is empty, nobody can sign in through SSO. A first-time SSO user gets a local account with the Reader role.
- Tenant. Sessions issued by
Loginare bound to the deployment’s default tenant. Handlers scope all reads and writes to the tenant in the verified session, never to a tenant named in a request.
Failure message values include Invalid credentials, Captcha verification failed,
Invalid two-factor code, SSO is not configured, SSO verification failed,
This account is not authorized for this instance and Unsupported authentication method.
Request: LoginRequest
| Field | Type | Description |
|---|---|---|
method | LoginRequest.AuthMethod | Which sign-in step this is. |
username | string | Account email, for AUTH_METHOD_CREDENTIALS. |
password | string | Account password, for AUTH_METHOD_CREDENTIALS. |
hcaptcha_token | string | Captcha response token. Checked only when the deployment enforces a captcha. |
oidc_token | string | OIDC ID token, for AUTH_METHOD_GOOGLE_OIDC. |
mfa_code | string | 6-digit TOTP code, for AUTH_METHOD_MFA_VERIFY. |
mfa_session | string | The mfa_session returned by the credentials step, for AUTH_METHOD_MFA_VERIFY. |
Reserved: field 2 (key).
Response: LoginResponse
| Field | Type | Description |
|---|---|---|
status | LoginResponse.Status | Outcome of this step. |
token | string | The session token (a signed JWT) on STATUS_SUCCESS. Send it as authorization: Bearer <token>. |
message | string | Human-readable outcome, safe to show to the user. |
mfa_session | string | Short-lived challenge to send back with AUTH_METHOD_MFA_VERIFY, on STATUS_MFA_REQUIRED. |
Logout
rpc Logout(LogoutRequest) returns (LogoutResponse);- Kind: Unary.
- Auth: Bearer session.
- Errors:
UNAUTHENTICATEDif the session carries no subject.INTERNALif the sessions could not be revoked. In that case nothing was revoked.
Revokes every session of the calling account, not only the one making the call. The
account is taken from the authenticated session. The token field in the request is accepted
for wire compatibility and is ignored, so one caller cannot end another account’s sessions.
Request: LogoutRequest
| Field | Type | Description |
|---|---|---|
token | string | Ignored. The session revoked is the one authenticating the call. |
Response: LogoutResponse
| Field | Type | Description |
|---|---|---|
success | bool | true once the sessions are revoked. |
EnrollTotp
rpc EnrollTotp(EnrollTotpRequest) returns (EnrollTotpResponse);- Kind: Unary.
- Auth: Bearer session. A caller may enrol their own account, and an org admin may enrol any account.
- Errors:
PERMISSION_DENIEDif the email is not the caller’s own account and the caller is not an org admin. An email that does not exist gets the same error, so the RPC cannot be used to test whether an account exists.INTERNALif the secret cannot be generated.
Generates a fresh TOTP secret and an otpauth:// provisioning URI (issuer FACE). Nothing is
stored until ConfirmTotp succeeds. Returns success: false with
User not found when the account disappears between the permission check and the lookup.
Request: EnrollTotpRequest
| Field | Type | Description |
|---|---|---|
email | string | Email of the account to enrol. |
Response: EnrollTotpResponse
| Field | Type | Description |
|---|---|---|
success | bool | Whether a secret was generated. |
secret | string | Base32 shared secret. Keep it for ConfirmTotp. |
provisioning_uri | string | otpauth:// URI, usually rendered as a QR code. |
message | string | Human-readable outcome. |
ConfirmTotp
rpc ConfirmTotp(ConfirmTotpRequest) returns (ConfirmTotpResponse);- Kind: Unary.
- Auth: Bearer session. Same rule as
EnrollTotp: the caller’s own account, or any account for an org admin. - Errors:
PERMISSION_DENIEDunder the same conditions asEnrollTotp.INTERNALif the secret cannot be saved.
Checks code against secret. On a match, the server stores the secret and turns on two-factor
sign-in for the account. A wrong code returns success: false with
Invalid code — please try again.
Request: ConfirmTotpRequest
| Field | Type | Description |
|---|---|---|
email | string | Email of the account being enrolled. |
secret | string | The secret returned by EnrollTotp. |
code | string | Current 6-digit code from the authenticator app. |
Response: ConfirmTotpResponse
| Field | Type | Description |
|---|---|---|
success | bool | true once two-factor is enabled. |
message | string | Human-readable outcome. |
UpdateUser
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);- Kind: Unary.
- Auth: Bearer session, org admin only. Service-account tokens are refused.
- Errors:
PERMISSION_DENIEDfor any role other than org admin.INTERNALif the change was saved but the account’s existing sessions could not be ended.
Updates the non-empty fields among email, role and password on the account identified
by user_id. After a successful change, every existing session of that account is revoked, so
the new role or password applies at the next sign-in. Some failures return success: false
with a message instead of an error: UserID required, No such user,
That email is already in use and Update failed.
Request: UpdateUserRequest
| Field | Type | Description |
|---|---|---|
user_id | string | Required. The account to change. |
email | string | New email. Empty leaves it unchanged. |
role | string | New role. Empty leaves it unchanged. |
password | string | New password. Empty leaves it unchanged. |
is_active | bool | Not applied. The account model has no active or disabled state. When true, the response message says the flag was not applied. To disable an account, remove it on the Admin page. |
Response: UpdateUserResponse
| Field | Type | Description |
|---|---|---|
success | bool | Whether the change was applied. |
message | string | Human-readable outcome. |
CreateInstance
rpc CreateInstance(CreateInstanceRequest) returns (CreateInstanceResponse);- Kind: Unary.
- Auth: Bearer session. Service-account tokens are refused.
- Errors: None beyond authentication.
Echoes the requested id back with success: true and records nothing. Instances are
provisioned by the platform, not through this RPC.
Request: CreateInstanceRequest
| Field | Type | Description |
|---|---|---|
id | string | Requested instance id, for example org-example-prod. |
name | string | Display name, for example Production Environment. |
Reserved: field 1 (license_key).
Response: CreateInstanceResponse
| Field | Type | Description |
|---|---|---|
success | bool | Always true. |
instance_id | string | The id from the request. |
message | string | Human-readable outcome. |
ListInstances
rpc ListInstances(ListInstancesRequest) returns (ListInstancesResponse) {
option deprecated = true;
}- Kind: Unary.
- Auth: Bearer session. This is the one
IdentityServiceRPC that service-account tokens may call. A service account has no user account, though, so it always gets the “could not establish which account is signed in” failure. - Errors: None. Failures come back as
success: falsewith amessage.
Deprecated (kept for one release). Its replacement is ListInstances on the platform’s
shared profile service. Returns the instances the calling account is a member of.
The response has four distinct states:
success | instances | Meaning |
|---|---|---|
true | non-empty | The caller’s instances. |
true | empty | The platform answered and the caller is a member of no instance. |
false | empty | Discovery failed, or the calling account could not be established. This does not mean the account has no instances. |
true | one local entry | A local development run with no platform to ask. The message says so. |
Request: ListInstancesRequest
No fields.
Response: ListInstancesResponse
| Field | Type | Description |
|---|---|---|
success | bool | See the state table above. |
instances | repeated InstanceInfo | Instances visible to the caller. |
message | string | Human-readable explanation, including why a list is empty. |
GenerateServiceAccountKey
rpc GenerateServiceAccountKey(GenerateServiceAccountKeyRequest) returns (GenerateServiceAccountKeyResponse);- Kind: Unary.
- Auth: Bearer session, org admin only. Service-account tokens are refused.
- Errors:
INVALID_ARGUMENTifnameis empty or is a name reserved for an internal credential.PERMISSION_DENIEDif the caller is not an org admin, if the session has no verified tenant, or iftenant_idnames a tenant other than the caller’s.INTERNALif the token cannot be issued.
Mints a signed service-account token with ROLE_SERVICE_ACCOUNT. The token is scoped to the
caller’s own tenant and valid for 365 days. Use it as a bearer token for machine clients
such as runners and integrations. What a service account may call is listed under
Roles. The key is returned once. Store it as a
secret.
Request: GenerateServiceAccountKeyRequest
| Field | Type | Description |
|---|---|---|
tenant_id | string | Optional. If set, it must equal the caller’s own tenant. The server never issues a key for another tenant. |
name | string | Required. Service-account name. The account id becomes sa-<name>. |
Response: GenerateServiceAccountKeyResponse
| Field | Type | Description |
|---|---|---|
api_key | string | The bearer token. Shown once. |
account | ServiceAccount | The account the key belongs to. |
ActivationService
Full name semantics.v1.ActivationService.
Licences are Ed25519-signed documents issued offline by the platform. FACE only verifies them
and never signs one. When a deployment has a licence configured, every authenticated call checks
it. An expired or invalid licence makes every call fail with PERMISSION_DENIED
(license expired or invalid). Service-account tokens are refused on this whole service.
GenerateLicense
rpc GenerateLicense(GenerateLicenseRequest) returns (GenerateLicenseResponse);- Kind: Unary.
- Auth: Bearer session.
- Errors: Always
UNIMPLEMENTED. FACE does not issue licences.
The messages are kept on the wire. The server does not read any request field.
Request: GenerateLicenseRequest
| Field | Type | Description |
|---|---|---|
email | string | Licensee email. |
auth_type | string | "user" or "sso". |
role | string | "admin", "writer" or "reader". |
subscription | string | "agent" or "basic". |
days | int32 | Expiration in days. |
expires_at | string | Optional override, YYYY-MM-DD. |
tenant_id | string | Tenant the licence is for. |
seats | int32 | Seat count. |
Response: GenerateLicenseResponse
| Field | Type | Description |
|---|---|---|
license_key | string | Never populated. |
expires_at | string | Never populated. |
username | string | Never populated. |
password | string | Never populated. |
user_profile_snippet | string | Never populated. |
ValidateLicense
rpc ValidateLicense(ValidateLicenseRequest) returns (ValidateLicenseResponse);- Kind: Unary.
- Auth: None. This RPC is exempt from bearer authentication.
- Errors: None. An unverifiable key returns
valid: false.
Returns valid: true only when the deployment has a licence verification key configured,
license_key carries a signature that verifies against it, and the current time is inside the
licence’s validity window. The key may be the signed licence JSON or that JSON base64-encoded.
The server logs only a hash of the key.
Request: ValidateLicenseRequest
| Field | Type | Description |
|---|---|---|
license_key | string | The signed licence, as JSON or base64-encoded JSON. |
Response: ValidateLicenseResponse
| Field | Type | Description |
|---|---|---|
valid | bool | Signature verified and within the validity window. |
customer_email | string | Not populated by the server. |
expires_at | string | Not populated by the server. |
remaining_days | int32 | Not populated by the server. |
subscription | string | Not populated by the server. |
ActivateLicense
rpc ActivateLicense(ActivateLicenseRequest) returns (ActivateLicenseResponse);- Kind: Unary.
- Auth: Bearer session.
- Errors: Always
UNIMPLEMENTED. The server has no handler for this RPC.
Request: ActivateLicenseRequest
| Field | Type | Description |
|---|---|---|
license_key | string | Licence to activate. |
Response: ActivateLicenseResponse
| Field | Type | Description |
|---|---|---|
success | bool | Never returned. |
message | string | Never returned. |
LandingService
Full name semantics.v1.LandingService.
Headline figures for the landing page. Both RPCs require a bearer session. The landing dashboard shows a customer’s operational data, so it is not readable before sign-in.
GetSystemStatus
rpc GetSystemStatus(GetSystemStatusRequest) returns (GetSystemStatusResponse);- Kind: Unary.
- Auth: Bearer session.
- Errors: None beyond authentication.
Currently returns an empty response: all four summaries are unset. Posture comes from a real fetch run (see Fetch & traces), and the server returns no placeholder figures.
Request: GetSystemStatusRequest
No fields.
Response: GetSystemStatusResponse
| Field | Type | Description |
|---|---|---|
posture | PostureSummary | Not populated. |
rules | RulesSummary | Not populated. |
hypothesis | HypothesisSummary | Not populated. |
twins | TwinsSummary | Not populated. |
GetDashboardStats
rpc GetDashboardStats(GetDashboardStatsRequest) returns (GetDashboardStatsResponse);- Kind: Unary.
- Auth: Bearer session.
- Errors: None beyond authentication.
Computes a few live counters and leaves every other field unset. Treat an unset field as “not reported”, not as zero:
dashboard_stats.total_active_agentscounts the runners thatConfigService.ListRunnersreports as running.twins_dashboard.action_queue_depthcounts the pending action cards, after operator decisions are applied.twins_dashboard.impact_potentialis the total value of the action cards that are undecided or approved, formatted as$<n>.<nn>M. Rejected cards are left out. The field is set only when that total is positive.
financial_metrics, profile_details and inference_outcomes are not set by this RPC.
Financial figures come from an analysis run. See
Analysis, posture & rules.
Request: GetDashboardStatsRequest
No fields.
Response: GetDashboardStatsResponse
| Field | Type | Description |
|---|---|---|
dashboard_stats | DashboardStats | Always present. Only total_active_agents is computed. |
financial_metrics | FinancialMetrics | Not set by this RPC. |
twins_dashboard | TwinsDashboardStats | Always present. Only action_queue_depth and impact_potential are computed. |
profile_details | ProfileDetails | Not set by this RPC. |
inference_outcomes | InferenceOutcomes | Not set by this RPC. |
Messages
ServiceAccount
| Field | Type | Description |
|---|---|---|
id | string | Account id, sa-<name>. |
tenant_id | string | The tenant the account acts in. |
name | string | Account name. |
role | Role | Always ROLE_SERVICE_ACCOUNT. |
Tenant
Defined in commons_defs.proto and used by no RPC on this page.
| Field | Type | Description |
|---|---|---|
id | string | Tenant id. |
name | string | Display name. |
subscription | SubscriptionTier | Subscription tier. |
seats | int32 | Seat count. |
base_cu_allowance | int32 | Base compute-unit allowance. |
InstanceInfo
| Field | Type | Description |
|---|---|---|
id | string | Instance id. |
name | string | Display name. |
role | string | The caller’s role on this instance. |
subscription | string | Subscription of the instance. |
last_accessed | string | Not populated by the server. |
dns | string | Address at which the instance is served. |
host_ip | string | Host address of the instance, when the platform records one. |
PostureSummary
| Field | Type | Description |
|---|---|---|
commerce_health | string | Commerce health label. |
logistics_health | string | Logistics health label. |
alert_count | int32 | Open alerts. |
RulesSummary
| Field | Type | Description |
|---|---|---|
rules_extracted | int32 | Rules extracted. |
domains_clustered | int32 | Domains clustered. |
HypothesisSummary
| Field | Type | Description |
|---|---|---|
running_simulations | int32 | Simulations in progress. |
validated_scenarios | int32 | Scenarios validated. |
TwinsSummary
| Field | Type | Description |
|---|---|---|
pending_approvals | int32 | Action cards awaiting approval. |
executed_actions | int32 | Actions executed. |
DashboardStats
| Field | Type | Description |
|---|---|---|
system_health | string | Not set by GetDashboardStats. |
tasks_completed_today | int32 | Not populated. Always 0. Treat it as absent, not as “nothing completed”. |
total_active_agents | int32 | Runners reported as running. 0 means no running runner was observed. |
uptime_hours | double | Not set by GetDashboardStats. |
error_rate | string | Not set by GetDashboardStats. |
latency_p95 | string | Not set by GetDashboardStats. |
FinancialMetrics
| Field | Type | Description |
|---|---|---|
revenue | string | Revenue figure. |
revenue_trend | string | Revenue trend. |
margin | string | Margin label. |
margin_value | string | Margin value. |
capex | string | Capital expenditure. |
capex_trend | string | Capex trend. |
opex | string | Operating expenditure. |
opex_trend | string | Opex trend. |
TwinsDashboardStats
| Field | Type | Description |
|---|---|---|
high_priority_match | string | Not set by GetDashboardStats. |
high_priority_recovery | string | Not set by GetDashboardStats. |
impact_potential | string | Total value of undecided and approved action cards, $<n>.<nn>M. Unset when the total is zero. |
impact_trend | string | Not set by GetDashboardStats. |
normal_priority_eta | string | Not set by GetDashboardStats. |
normal_priority_premium | string | Not set by GetDashboardStats. |
action_queue_depth | int32 | Pending action cards, after operator decisions. |
pipeline_throughput | string | Not set by GetDashboardStats. |
ProfileDetails
| Field | Type | Description |
|---|---|---|
license_type | string | Licence type label. |
remaining_days | string | Days left on the licence. |
InferenceOutcomes
| Field | Type | Description |
|---|---|---|
confidence_score | double | Confidence score. |
stochastic_candles | repeated double | Series values. |
model_version | string | Model version label. |
Enums
LoginRequest.AuthMethod
| Value | Meaning |
|---|---|
AUTH_METHOD_UNSPECIFIED | Not set. Login fails with Unsupported authentication method. |
AUTH_METHOD_GOOGLE_OIDC | Sign in with an OIDC ID token from the deployment’s configured issuer. |
AUTH_METHOD_CREDENTIALS | Username (email) and password. |
AUTH_METHOD_MFA_VERIFY | Second step: TOTP challenge response. |
Reserved: value 1 (AUTH_METHOD_LICENSE_KEY).
LoginResponse.Status
| Value | Meaning |
|---|---|
STATUS_UNSPECIFIED | Not set. |
STATUS_SUCCESS | Signed in. token is set. |
STATUS_FAILURE | Not signed in. message says why. |
STATUS_MFA_REQUIRED | Password accepted. Send the TOTP code with mfa_session. |
Role
| Value | Meaning |
|---|---|
ROLE_UNSPECIFIED | No role. A session whose role is not recognised is refused. |
ROLE_ORG_ADMIN | Administrator. |
ROLE_WRITER | Editor. |
ROLE_READER | Viewer. |
ROLE_SERVICE_ACCOUNT | Machine credential from GenerateServiceAccountKey. |
SubscriptionTier
| Value | Meaning |
|---|---|
SUBSCRIPTION_TIER_UNSPECIFIED | Not set. |
SUBSCRIPTION_TIER_LITE | Lite. Dedicated-only features, such as creating a Databricks cluster, are refused. |
SUBSCRIPTION_TIER_DEDICATED | Dedicated. |
SUBSCRIPTION_TIER_ENTERPRISE | Enterprise. |