diff --git a/src/otari/_client/api/auth_api.py b/src/otari/_client/api/auth_api.py index e638fea..3523ce5 100644 --- a/src/otari/_client/api/auth_api.py +++ b/src/otari/_client/api/auth_api.py @@ -1408,7 +1408,7 @@ def set_dashboard_password_v1_auth_password_put( ) -> PasswordResponse: """Set Dashboard Password - Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. Setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. + Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. The operator setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. :param set_password_request: (required) :type set_password_request: SetPasswordRequest @@ -1476,7 +1476,7 @@ def set_dashboard_password_v1_auth_password_put_with_http_info( ) -> ApiResponse[PasswordResponse]: """Set Dashboard Password - Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. Setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. + Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. The operator setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. :param set_password_request: (required) :type set_password_request: SetPasswordRequest @@ -1544,7 +1544,7 @@ def set_dashboard_password_v1_auth_password_put_without_preload_content( ) -> RESTResponseType: """Set Dashboard Password - Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. Setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. + Set or change the password the caller signs in to the dashboard with. Always the caller's own identity. Supply ``email`` when it has no sign-in address yet, which is the state first boot leaves the operator in, and ``current_password`` when it already has a password and the request is authenticated by the session cookie. The master key in a header is what excuses ``current_password``, which is how a forgotten password is recovered; it does not excuse ``email``, because an identity with no address has nothing to sign in with whoever is asking. The operator setting a password for the first time retires master-key sign-in on this deployment. Every other session this identity holds ends, the caller's own excepted, so a cookie stolen before the change does not outlive it. :param set_password_request: (required) :type set_password_request: SetPasswordRequest diff --git a/src/otari/_client/api/bootstrap_api.py b/src/otari/_client/api/bootstrap_api.py index 16e3087..a6cff44 100644 --- a/src/otari/_client/api/bootstrap_api.py +++ b/src/otari/_client/api/bootstrap_api.py @@ -53,7 +53,7 @@ def get_bootstrap_v1_bootstrap_get( ) -> DeploymentBootstrap: """Get Bootstrap - Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The one database read is a ``LIMIT 1`` probe for any identity holding a password, over a table a standalone deployment keeps one row per person in. It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. + Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The database read is two primary-key lookups: the ``tenancy_bootstrap_user_id`` marker, and the identity it names, to answer whether *that* identity holds a password (#702). It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -116,7 +116,7 @@ def get_bootstrap_v1_bootstrap_get_with_http_info( ) -> ApiResponse[DeploymentBootstrap]: """Get Bootstrap - Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The one database read is a ``LIMIT 1`` probe for any identity holding a password, over a table a standalone deployment keeps one row per person in. It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. + Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The database read is two primary-key lookups: the ``tenancy_bootstrap_user_id`` marker, and the identity it names, to answer whether *that* identity holds a password (#702). It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. :param _request_timeout: timeout setting for this request. If one number provided, it will be total request @@ -179,7 +179,7 @@ def get_bootstrap_v1_bootstrap_get_without_preload_content( ) -> RESTResponseType: """Get Bootstrap - Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The one database read is a ``LIMIT 1`` probe for any identity holding a password, over a table a standalone deployment keeps one row per person in. It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. + Return the deployment context the dashboard shell renders from. Public: the shell fetches this before it knows whether it can authenticate. That is also why ``sign_in_methods`` is answered here rather than behind a credential, and it publishes nothing an unauthenticated caller could not already learn by trying both credentials against the sign-in endpoint. The database read is two primary-key lookups: the ``tenancy_bootstrap_user_id`` marker, and the identity it names, to answer whether *that* identity holds a password (#702). It runs only in standalone mode: a hybrid gateway has no session to describe, and ``get_db_if_needed`` hands it no session to read one from. :param _request_timeout: timeout setting for this request. If one number provided, it will be total request diff --git a/src/otari/_client/models/create_session_request.py b/src/otari/_client/models/create_session_request.py index ae8eae7..52740c4 100644 --- a/src/otari/_client/models/create_session_request.py +++ b/src/otari/_client/models/create_session_request.py @@ -29,7 +29,7 @@ class CreateSessionRequest(BaseModel): Sign in to the dashboard with exactly one credential. A flat body with an optional field per credential, rather than a tagged union: it is one extra key on the wire, it generates a client type a hand-written form can fill in, and the validator below makes the two forms exclusive anyway. The example carries one credential, because a generated example is a body somebody will post: the schema alone would produce every field at once, which is the one shape the validator below refuses. """ # noqa: E501 email: Optional[Annotated[str, Field(strict=True, max_length=255)]] = Field(default=None, description="The identity's sign-in address.") - master_key: Optional[Annotated[str, Field(strict=True, max_length=512)]] = Field(default=None, description="The gateway master key; verified once and never stored by the browser. Accepted only while no identity on this deployment has a password (see GET /v1/bootstrap).") + master_key: Optional[Annotated[str, Field(strict=True, max_length=512)]] = Field(default=None, description="The gateway master key; verified once and never stored by the browser. Accepted only while the operator identity has no password, which is to say while nobody has claimed this deployment (see GET /v1/bootstrap).") password: Optional[Annotated[str, Field(strict=True, max_length=72)]] = Field(default=None, description="The identity's password.") __properties: ClassVar[List[str]] = ["email", "master_key", "password"] diff --git a/src/otari/_client/models/deployment_bootstrap.py b/src/otari/_client/models/deployment_bootstrap.py index 2beb791..f690e5c 100644 --- a/src/otari/_client/models/deployment_bootstrap.py +++ b/src/otari/_client/models/deployment_bootstrap.py @@ -31,7 +31,7 @@ class DeploymentBootstrap(BaseModel): mail_ready: StrictBool = Field(description="Whether this deployment can deliver a message carrying a link back to itself (an invitation's accept link, and the verification and reset links to come), not merely whether a transport is configured: it also needs to know its own public URL to put in one. Lets the dashboard disable or hide a mail-dependent affordance instead of offering one that would fail at send time. Every message this control plane sends carries such a link, which is why this is one flag and not one per feature. False for a hybrid gateway, whose control plane is otari.ai and which sends no mail of its own.") management_url: Optional[StrictStr] = Field(description="Where the authoritative control plane lives when it is not this deployment. Set for a hybrid gateway so its landing page can link to otari.ai; null otherwise.") session_type: StrictStr = Field(description="The kind of session this deployment issues, not whether the caller holds one. 'local_operator' is the standalone operator sign-in (see sign_in_methods for which credential it currently accepts), 'hosted_user' an otari.ai account, and 'none' a deployment that issues no management session at all.") - sign_in_methods: List[StrictStr] = Field(description="How POST /v1/auth/session may be authenticated right now, sorted. 'master_key' is the first-boot credential and is offered until some identity on this deployment has a password; 'password' replaces it from then on, and the master key stays the credential for the management API. Empty for a hybrid gateway, which issues no session. The login page renders from this rather than trying a credential to find out.") + sign_in_methods: List[StrictStr] = Field(description="How POST /v1/auth/session may be authenticated right now, sorted. 'master_key' is the first-boot credential and is offered until the operator identity has a password, which is what claiming the deployment means; 'password' replaces it from then on, and the master key stays the credential for the management API. Empty for a hybrid gateway, which issues no session. The login page renders from this rather than trying a credential to find out.") surfaces: List[StrictStr] = Field(description="Management API groups this deployment serves, sorted, which is what its dashboard pages gate on. Named surfaces, not capabilities: capability is otari.ai's word for the entitlement (licensing) axis, and this is the deployment (topology) axis. Empty for a hybrid gateway.") __properties: ClassVar[List[str]] = ["deployment_type", "mail_ready", "management_url", "session_type", "sign_in_methods", "surfaces"] diff --git a/src/otari/_client/models/password_response.py b/src/otari/_client/models/password_response.py index 79faca9..a9d7480 100644 --- a/src/otari/_client/models/password_response.py +++ b/src/otari/_client/models/password_response.py @@ -28,7 +28,7 @@ class PasswordResponse(BaseModel): What the identity signs in with now. """ # noqa: E501 email: StrictStr = Field(description="The address this identity signs in with.") - master_key_sign_in_retired: StrictBool = Field(description="Always true once this succeeds: some identity on this deployment now has a password, so POST /v1/auth/session no longer accepts the master key. It stays the credential for the management API.") + master_key_sign_in_retired: StrictBool = Field(description="Whether POST /v1/auth/session has stopped accepting the master key as a dashboard login. True once the operator identity has a password, which is what claiming the deployment means; a member setting their own password leaves an unclaimed deployment on the master key. Either way the master key stays the credential for the management API.") __properties: ClassVar[List[str]] = ["email", "master_key_sign_in_retired"] model_config = ConfigDict(