Skip to main content

Manage users, API keys and access control

You invite users, create an API key, grant access to an account resource and inspect effective permissions. You can also manage invitations and membership at organization scope.

Note: Balancer is in beta. Endpoints, fields and behavior may change before general availability, and the feature must be enabled on your account before use. Contact your NetActuate account manager to request access.

Prerequisites​

  • Balancer access and a key in the BALANCER_API_KEY environment variable with permission for these operations.
  • The API host shown in the Balancer portal. Replace <your-api-host> in every example with that host.
  • A shell, curl and Python 3 for examples that build JSON from environment variables.
  • Administrator access for the account or organization you manage. Set ACCOUNT_ID and ORGANIZATION_ID from your selected portal context, MEMBER_ID to an account membership identifier, and HTTP_LB_ID to the resource you will grant.

Resource identifiers come from your API responses. Set each variable when its value is available, before the first step that uses it.

Environment variableValue
ACCOUNT_IDReturned resource identifier, or your selected scope identifier.
HTTP_LB_IDReturned resource identifier, or your selected scope identifier.
MEMBER_IDReturned resource identifier, or your selected scope identifier.
ORGANIZATION_IDReturned resource identifier, or your selected scope identifier.

For an identifier, enter the value returned for your resource and export it:

read -r -p 'ACCOUNT_ID: ' ACCOUNT_ID
export ACCOUNT_ID

Steps​

  1. Invite an account member.

    curl --silent --show-error --include \
    --request POST \
    --url "https://<your-api-host>/accounts/$ACCOUNT_ID/invitations" \
    --header "x-api-key: $BALANCER_API_KEY" \
    --header "Content-Type: application/json" \
    --data-binary '{"invitation":{"email":"user@example.com","isAdmin":false}}'

    API reference: Create an account invitation

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200,
    "result": "success"
    }
  2. If you manage organization membership, invite at organization scope.

    curl --silent --show-error --include \
    --request POST \
    --url "https://<your-api-host>/organizations/$ORGANIZATION_ID/invitations" \
    --header "x-api-key: $BALANCER_API_KEY" \
    --header "Content-Type: application/json" \
    --data-binary '{"invitation":{"email":"user@example.com","isAdmin":false}}'

    API reference: Create an organization invitation

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200,
    "result": "success"
    }
  3. Create a key with explicit read-only access.

    curl --silent --show-error --include \
    --request POST \
    --url "https://<your-api-host>/user/api-keys" \
    --header "x-api-key: $BALANCER_API_KEY" \
    --header "Content-Type: application/json" \
    --data-binary '{"apiKey":{"name":"monitoring","accessMode":"read-only"}}'

    API reference: Create an API key for your account user

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200
    }

    Keep the returned credential private. TODO(verify): Credential return fields, display-once behavior and the key-to-account selection procedure.

  4. Grant the account member read-only access to one HTTP load balancer.

    python3 - <<'PYBODY' | \
    curl --silent --show-error --include \
    --request POST \
    --url "https://<your-api-host>/accounts/$ACCOUNT_ID/resource-permissions" \
    --header "x-api-key: $BALANCER_API_KEY" \
    --header "Content-Type: application/json" \
    --data-binary @-
    import json, os
    print(json.dumps({'resourcePermission': {'resource': {'resourceType': 'httpLb', 'resourceId': int(os.environ['HTTP_LB_ID'])}, 'grantee': {'granteeType': 'member', 'granteeId': int(os.environ['MEMBER_ID'])}, 'access': 'read-only'}}))
    PYBODY

    API reference: Create a resource permission grant

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200,
    "result": "success"
    }
  5. Inspect that member's effective access.

    curl --silent --show-error --include \
    --request GET \
    --url "https://<your-api-host>/accounts/$ACCOUNT_ID/members/$MEMBER_ID/effective-access" \
    --header "x-api-key: $BALANCER_API_KEY"

    API reference: Return effective resource access for an account member

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200,
    "result": "success"
    }
  6. Inspect your effective account access.

    curl --silent --show-error --include \
    --request GET \
    --url "https://<your-api-host>/accounts/$ACCOUNT_ID/effective-access" \
    --header "x-api-key: $BALANCER_API_KEY"

    API reference: Return effective resource access for the authenticated account user

    Expected: HTTP 200. The following shows the response fields to check; additional data depends on your saved resources. Resource identifiers are illustrative.

    {
    "code": 200,
    "result": "success"
    }

Verify​

Test the intended API operation using the member's own credential in the intended account context. A resource grant does not establish access to other accounts or resources. Review API-surface grants, teams and capability grants when effective access differs.

Troubleshooting​

SymptomCauseFix
API returns 401Key mode, membership or resource permission denies the operationCheck active membership, selected account, expiry, revocation and effective grants.
Grant targets the wrong userIdentity identifier was used instead of membership identifierUse the account membership identifier.
Organization access differs from account accessOrganization and account memberships are separateInspect membership and grants at the intended scope.

Limits and defaults​

SettingLimit or default
API key name1 to 64 characters
API key access modeDefault admin; read-only, write or admin
Invitation expiryDefault 7 days
Invitation administrator flagDefault false
Resource accessread-only, write or admin

API status codes​

StatusMeaning
200Request succeeds; inspect returned data.
400Invalid arguments or configuration.
401Authentication or authorization denied.
409Resource state conflicts with the operation.
500The request encounters a server error.
  • DELETE /accounts/{accountId}/api-surface-fallbacks/{apiSurfaceFallbackId}
  • DELETE /accounts/{accountId}/api-surface-grants/{apiSurfaceGrantId}
  • DELETE /accounts/{accountId}/capability-grants/{capabilityGrantId}
  • DELETE /accounts/{accountId}/invitations/{invitationId}
  • DELETE /accounts/{accountId}/members/{accountUserId}
  • DELETE /accounts/{accountId}/resource-permissions/{resourcePermissionId}
  • DELETE /accounts/{accountId}/sso-providers/{ssoProviderId}
  • DELETE /accounts/{accountId}/teams/{teamId}
  • DELETE /accounts/{accountId}/teams/{teamId}/members/{accountUserId}
  • DELETE /organizations/{organizationId}
  • DELETE /organizations/{organizationId}/accounts/{accountId}
  • DELETE /organizations/{organizationId}/capability-grants/{capabilityGrantId}
  • DELETE /organizations/{organizationId}/invitations/{invitationId}
  • DELETE /organizations/{organizationId}/sso-providers/{ssoProviderId}
  • DELETE /organizations/{organizationId}/teams/{teamId}
  • DELETE /user/api-keys/{apiKeyId}
  • DELETE /user/mfa-factors/{mfaFactorId}
  • GET /accounts/{accountId}
  • GET /accounts/{accountId}/api-surface-fallbacks
  • GET /accounts/{accountId}/api-surface-grants
  • GET /accounts/{accountId}/audit-logs
  • GET /accounts/{accountId}/auth-logs
  • GET /accounts/{accountId}/capability-grants
  • GET /accounts/{accountId}/effective-access
  • GET /accounts/{accountId}/invitations
  • GET /accounts/{accountId}/members
  • GET /accounts/{accountId}/members/{accountUserId}
  • GET /accounts/{accountId}/members/{accountUserId}/effective-access
  • GET /accounts/{accountId}/resource-permissions
  • GET /accounts/{accountId}/sso-providers
  • GET /accounts/{accountId}/sso-providers/{ssoProviderId}
  • GET /accounts/{accountId}/teams
  • GET /accounts/{accountId}/teams/{teamId}
  • GET /accounts/{accountId}/teams/{teamId}/members
  • GET /auth/contexts
  • GET /organizations
  • GET /organizations/{organizationId}
  • GET /organizations/{organizationId}/accounts
  • GET /organizations/{organizationId}/audit-logs
  • GET /organizations/{organizationId}/auth-logs
  • GET /organizations/{organizationId}/capability-grants
  • GET /organizations/{organizationId}/invitations
  • GET /organizations/{organizationId}/members
  • GET /organizations/{organizationId}/sso-providers
  • GET /organizations/{organizationId}/sso-providers/{ssoProviderId}
  • GET /organizations/{organizationId}/teams
  • GET /organizations/{organizationId}/teams/{teamId}
  • GET /user
  • GET /user/account-invitations
  • GET /user/api-keys
  • GET /user/mfa-factors
  • GET /user/organization-invitations
  • PATCH /accounts/{accountId}
  • PATCH /accounts/{accountId}/invitations/{invitationId}
  • PATCH /accounts/{accountId}/members/{accountUserId}
  • PATCH /accounts/{accountId}/resource-permissions/{resourcePermissionId}
  • PATCH /accounts/{accountId}/sso-providers/{ssoProviderId}
  • PATCH /accounts/{accountId}/teams/{teamId}
  • PATCH /organizations/{organizationId}
  • PATCH /organizations/{organizationId}/invitations/{invitationId}
  • PATCH /organizations/{organizationId}/sso-providers/{ssoProviderId}
  • PATCH /organizations/{organizationId}/teams/{teamId}
  • PATCH /user
  • PATCH /user/api-keys/{apiKeyId}
  • PATCH /user/mfa-factors/{mfaFactorId}
  • POST /accounts/{accountId}/api-surface-fallbacks
  • POST /accounts/{accountId}/api-surface-grants
  • POST /accounts/{accountId}/capability-grants
  • POST /accounts/{accountId}/invitations
  • POST /accounts/{accountId}/invitations/{invitationId}/resend
  • POST /accounts/{accountId}/members/{accountUserId}/api-keys/revoke
  • POST /accounts/{accountId}/members/{accountUserId}/sessions/revoke
  • POST /accounts/{accountId}/members/{accountUserId}/transfer-master
  • POST /accounts/{accountId}/resource-permissions
  • POST /accounts/{accountId}/sso-providers
  • POST /accounts/{accountId}/sso-providers/{ssoProviderId}/verify
  • POST /accounts/{accountId}/teams
  • POST /accounts/{accountId}/teams/{teamId}/members
  • POST /auth/context
  • POST /auth/email-verifications/{token}/confirm
  • POST /auth/invitations/{invitationToken}/accept
  • POST /auth/login
  • POST /auth/login/mfa
  • POST /auth/onboarding
  • POST /auth/organization-invitations/{invitationToken}/accept
  • POST /auth/password-resets
  • POST /auth/password-resets/{token}/confirm
  • POST /auth/phone-verifications/{token}/confirm
  • POST /organizations
  • POST /organizations/{organizationId}/accounts
  • POST /organizations/{organizationId}/accounts/{accountId}/members/{accountUserId}/api-keys/revoke
  • POST /organizations/{organizationId}/accounts/{accountId}/members/{accountUserId}/sessions/revoke
  • POST /organizations/{organizationId}/capability-grants
  • POST /organizations/{organizationId}/invitations
  • POST /organizations/{organizationId}/invitations/{invitationId}/resend
  • POST /organizations/{organizationId}/members/{organizationUserId}/transfer-master
  • POST /organizations/{organizationId}/sso-providers
  • POST /organizations/{organizationId}/sso-providers/{ssoProviderId}/verify
  • POST /organizations/{organizationId}/teams
  • POST /user/account-invitations/{invitationId}/accept
  • POST /user/api-keys
  • POST /user/email-verifications
  • POST /user/mfa-factors
  • POST /user/mfa-factors/{mfaFactorId}/verify
  • POST /user/organization-invitations/{invitationId}/accept
  • POST /user/phone-verifications
  • POST /user/phone-verifications/{challengeId}/confirm
  • POST /user/recovery-codes/rotate
  • POST /user/sessions/revoke

API reference​

Need Help?​

Contact your account manager or use the Balancer portal.