jumpserver/jumpserver · error · JMSException

perm_account_invalid

perm_account_invalid

Error message

Account not found

What it means

Raised in _validate_perm when get_permed_account returns no account or an account with empty actions — i.e. the user has no usable grant of this asset account for the protocol. Code is 'perm_account_invalid'.

Source

Thrown at apps/authentication/api/connection_token.py:737

        if ticket:
            data['from_ticket'] = ticket

        if ticket or self.need_face_verify:
            data['is_active'] = False
        if self.face_monitor_token:
            FaceMonitorContext.get_or_create_context(self.face_monitor_token, self.request.user.id)
            data['face_monitor_token'] = self.face_monitor_token
        return data

    @staticmethod
    def get_permed_account(user, asset, account_alias, protocol):
        return ConnectionToken.get_user_permed_account(user, asset, account_alias, protocol)

    def _validate_perm(self, user, asset, account_alias, protocol):
        account = self.get_permed_account(user, asset, account_alias, protocol)
        if not account or not account.actions:
            msg = _('Account not found')
            raise JMSException(code='perm_account_invalid', detail=msg)
        if account.date_expired < timezone.now():
            msg = _('Permission expired')
            raise JMSException(code='perm_expired', detail=msg)
        return account

    def _record_operate_log(self, acl, asset):
        from audits.handler import create_or_update_operate_log
        with tmp_to_org(asset.org_id):
            after = {
                str(_('Assets')): str(asset),
                str(_('Account')): self.input_username
            }
            object_name = acl._meta.object_name
            resource_type = acl._meta.verbose_name
            create_or_update_operate_log(
                acl.action, resource_type, resource=acl,
                after=after, object_name=object_name
            )

View on GitHub (pinned to 6ec464fabd)

Solutions

  1. Verify the user actually has an asset permission granting this account (check the asset permission's accounts and actions in the admin UI)
  2. Confirm org context: request with the correct X-JMS-ORG header matching the asset's org
  3. Re-check exact account username/alias; re-fetch the permed-account list before requesting the token
Defensive patterns

Strategy: try-catch

Validate before calling

accounts = get_user_permed_accounts(user, asset, protocol)
if not any(a['username'] == account_alias and a.get('actions') for a in accounts):
    raise PermissionError('no usable grant for this account')

Try / catch

try:
    resp = client.create_connection_token(...)
except JMSException as e:
    if e.code == 'perm_account_invalid':
        refresh_permission_cache(); show_grant_dialog()

Prevention

When it happens

Trigger: Calling connection-token validate/create/exchange for an (asset, account_alias, protocol) combination the user has no asset permission for, or whose grant has empty 'actions'; also when the account alias matches nothing on the asset.

Common situations: Permission was revoked or the grant was created without actions; wrong account name; user from a different organization (get_user_permed_account is org-scoped); stale cached permission list on the client side.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of jumpserver/jumpserver@6ec464fabd (2026-08-28). Data as JSON: /api/errors/f8b2d8bd0581177c. Report an issue: GitHub.