Admin
The Wallet Dashboard
The app-scoped surface where end users review activity and manage grants and delegated credentials.
The Wallet at wallet.alterauth.com is a hosted, app-scoped dashboard where end users manage the grants and delegated credentials associated with one Alter app. Users enter through an app-specific Wallet link and authenticate with that app’s configured identity provider. Each Wallet session is bound to both the app and the signed-in identity.
For end users, it answers three questions:
- What access does this app have? The user’s OAuth connections, managed-secret grants, scopes, status, and delegated agents for the current app.
- What did the app do with it? An activity feed showing calls made on the user’s behalf, with the application-supplied
reasonwhen present. - How is access granted or removed? Managed-secret access can be delegated to an agent from the Wallet, which needs proof of the user’s own Wallet sign-in (Delegating to an agent); OAuth grants and managed-secret delegations have explicit revoke actions.
For developers, it eliminates the need to build any of the above in-product.
How a user signs in
Section titled “How a user signs in”The Wallet sign-in link carries the app context. The user authenticates through that app’s Auth0, Clerk, Okta, WorkOS, or custom OIDC configuration, then sees only grants and activity belonging to that app and identity. The generic sign-in page cannot infer an app; without app context, it asks the user to return through the link supplied by the application.
There is no separate Wallet password or per-app registration form. A successful OIDC exchange creates a Wallet session bound to the resolved app user.
What an end user sees
Section titled “What an end user sees”- Dashboard — connected-account, grant, and recent-activity totals; active OAuth connections; recent activity; and a pending-approval banner when action is required.
- OAuth Connections — grants grouped by provider account, with scopes, status, last-used time, policy details, and a per-grant revoke action. On a connection’s Sibling grants tab, New grant creates another grant on the same provider account and can authorize an agent on it in the same step (one the user has already authorized in the application). That dialog offers May share this access with other agents, with the number of further hops left (“up to N more hops”), only when the application allows agent sharing for the provider; otherwise the agent gets the access without the ability to pass it on. If the application turns agent sharing off while the dialog is open, creating the grant with sharing on is refused and nothing is created (
grant_not_delegable): the dialog keeps the agent, the label and the expiry, removes the sharing choice and says why, and creating the grant again authorizes the agent without onward sharing. The Delegated agents tab shows the agents using the connection and the agents they shared it with; an agent that was allowed to share the access is marked No longer allowed to share this access with other agents once the application turns agent sharing off for the provider, or limits it so that agent has no further hop. - Managed Secrets — managed-secret grants and the agents authorized through each one, with All, With agents, and No agents filters; on each grant’s Agents tab, a Delegate to agent action and per-delegation revocation. Delegation from the Wallet covers both a user’s own grants and access shared through an identity-provider group. Whether it is offered at all is decided by three independent conditions: the application can switch off Wallet delegation for a credential entirely through that credential’s delegation limit; access that has expired can no longer be delegated; and access shared through a group additionally requires the application to have enabled group delegation on that credential. When delegation is unavailable, the Agents tab explains why instead of hiding the action silently. The agent picker offers agents the user has already authorized in the application and agents the application has enabled for that credential, limited to agents that are permitted to use it. In the dialog the user sets the terms of the delegation: an optional expiry, which can be no later than the credential’s own expiry or the lifetime limit the application configured, and — where the application permits onward delegation — whether the agent may pass the access on to another agent (May share this access with other agents), with the number of further hops the application’s policy leaves (“up to N more hops”). For a new delegation that choice starts off. Allowed request methods lets the user limit the agent to fewer HTTP methods than their own access allows — for example a read-only agent that may send
GETbut notPOST. Only the methods the user’s own access allows are offered, and all of them start selected; deselecting one limits the agent to the rest, and Alter refuses any other method the agent sends before the provider is called. The limit belongs to this delegation alone: the user’s own access and other agents’ delegations keep their methods. A request for a method the user’s access does not allow is refused (delegation_methods_exceed_parent) and nothing is delegated. The agent’s row on the Agents tab shows the limit (Only GET), and Edit access reopens the dialog on that agent with its current terms filled in; if that agent can no longer be given the access, the dialog says so and selects no other agent. A stored limit that cannot be read is shown as Method limit unreadable: every request the agent makes with the credential is refused until the user sets or removes the limit. The dialog states the outcome under the method list: No method limit, Limited to: the methods the agent will have, or, with nothing selected, that at least one method must be chosen. When the user’s own access allows no methods, the dialog says so. Changing other terms keeps the limit as it is. Deselecting or selecting methods replaces it with exactly the selected methods. With no limit stored, ending with every method selected stays no limit. Remove method limit removes the limit, so the agent can again use every method the user’s access allows. When the agent already holds access that it may share and the application’s policy no longer permits onward delegation, the choice is still shown, turned on, and can only be turned off. Authorizing an agent that already holds access replaces its current terms rather than adding a second delegation, and the dialog says so before the confirmation. If the application stops permitting the chosen agent to use the credential while the dialog is open, authorizing is refused with a message that says so (agent_allowlist_exceeded), nothing is delegated, and the agent list refreshes. Authorizing needs proof of the user’s own Wallet sign-in (Delegating to an agent). - Approvals — pending and historical HITL approvals, including Approve and Deny actions while the user’s gate is pending.
- Limits — the user’s account-wide limits, the limits the application set on the user’s account, the user’s limits for each connection, and the company or app restrictions on each connection in one view. The list is searchable.
- Activity — the app-scoped audit activity visible to this end user, including method, provider, status, latency, and the application’s
reasonwhen present. - Settings — the name and email resolved from the Wallet identity.
Delegating to an agent
Section titled “Delegating to an agent”Every Wallet request authenticates with an identity-provider token for the user, and the application can hold a token for the same user, so a token alone never authorizes an agent. Delegating — authorizing an agent on a managed secret’s Agents tab, or creating a grant for an agent with New grant on this connection — also needs proof of the user’s own Wallet sign-in. The Wallet keeps that proof for as long as its sign-in session lasts and discards it at sign-out.
wallet_session_required(HTTP 401) — the Wallet session carries no proof: it began before the requirement, or the proof expired. The Wallet shows Sign in again; after signing in, the user fills in the form again and repeats the delegation.- HTTP 503 — the store that holds sign-in proofs is temporarily unavailable, and nothing was delegated. The Wallet says Try again in a few minutes, or, when the proof could not be saved at sign-in, offers Sign in again a few minutes later (the form is then filled in again).
The delegation’s audit row records the Wallet sign-in proof, when it was verified, and when the identity provider authenticated the user.
Updating OAuth permissions
Section titled “Updating OAuth permissions”An end user can update a grant’s permissions or reconnect a provider-broken grant from OAuth Connections. The Wallet opens the provider authorization window and keeps the result visible in the dialog.
For an Alter-managed OAuth client, newly requested permissions may be unavailable because the managed client is not approved for them. The Wallet identifies this condition as managed_oauth_scope_approval_required, instructs the user to contact the application administrator, and offers re-authorization again afterwards. The administrator cannot widen an Alter-managed client themselves: they either narrow the application’s configured permissions to the approved set or ask Alter to approve the additional ones. Until one of those happens, every re-authorization attempt fails identically. This Wallet recovery restarts re-authorization for the existing grant; it does not create a new Connect session.
Limits and restrictions in the Wallet
Section titled “Limits and restrictions in the Wallet”The Wallet calls policies limits when the user owns them and restrictions when the company, the app, or a shared-from connection owns them. The top-level Limits page is an aggregate rather than an account-only list:
- Your account-wide limits apply to every account connected directly to the signed-in user and are editable in the Wallet.
- Set by the application shows the rules the application set on the user’s account, or on an identity-provider group the user belongs to (see Set by the application). They are read-only.
- Your limits for this connection apply to one OAuth or managed-secret grant. They remain viewable after expiry or revocation; inactive connections are read-only.
- Company and app restrictions show organization, application, provider, and agent policies that also affect a connection, and restrictions from the connection this was shared from show ancestor-connection policies. They still apply even if the user removes their own limit. They are read-only and disclosure-safe: the Wallet explains the effect and condition shape without exposing developer-only approver identities or internal configuration.
Selecting a policy opens the same viewer used by the developer portal. Owned rules show complete operation and parameter conditions; inherited controls show disclosure-safe summaries instead of developer-only values. Each connection’s Limits tab also shows every other limit and restriction on the connection, the connection lifetime, and the permission ceiling.
End users can create self-scoped narrowing rules for request-value conditions, approval requirements, time windows, quotas, and content matching. Provider-operation discovery supplies operation and parameter suggestions in the shared editor. IP allowlists and restriction rules are operator-controlled and cannot be authored in the Wallet.
Choose Add personal limit to start with approval, or select a usage limit or allowed times. These choices need no example HTTP request. More options reveals conditional approval and the structured/JSON editor without changing the draft. Existing definitions expose their full controls when edited. New or changed personal approval definitions require an explicit approver, shown before review: delegated and managed-secret access cannot rely on an implicit connection owner. Renaming or describing an existing OAuth rule preserves its approval definition, including a supported connection-owner default; it does not require changing who can approve.
Review shows the exact definition before Save personal limit; editing, enabling, disabling, and deleting also require review. Removing a personal limit never removes company restrictions. Connection-level limits can be created from that connection’s Limits tab; account-wide limits are separate.
Set by the application
Section titled “Set by the application”An application can restrict one of its users, or everyone in an identity-provider group, from the developer portal, the CLI, or a policy file (see Restrict one user or one group). Those rules apply to every request the user makes through the application, whichever connection or agent carries it, including connections shared through a group.
The Wallet shows each of them under the user’s account-wide limits, in a separate read-only group headed Set by and the application’s name. A rule that reaches the user through a group names that group (for example, “Set by Acme for the Contractors group”). Each row shows a summary of what the rule restricts, with the same disclosure-safe detail as other company and app restrictions: no controls, no name or description, and nothing that identifies the developer who set it. The connection Limits tab and the overview mark the same rules.
The user cannot edit, disable, or delete these rules; only the application can. In the other direction, the application sees the user’s own limits but cannot change or remove them. A group rule follows the membership the identity provider last reported, so a user who has left a group may still see its rule until the provider reports the change or the user signs in again; the user can raise it with the application, which can see the same rule.
What the developer configures
Section titled “What the developer configures”Branding: the Wallet shell uses Alter branding. App and provider names appear where they identify a grant or action, but app logo and color settings do not rebrand the Wallet.
Reason text: the most useful field in the activity feed is reason — the human-readable explanation of why the application made each call. Pass it on every app.request():
await app.request(method, url, grant_id=g, reason="Sync calendar events on user-triggered refresh")Reasons appear verbatim in the Wallet. Treat them as user-facing copy.
Approvers: when an approval policy is configured, the designated approver sees a redacted request summary: method, host, path, provider, grant information, policy-evaluated operation or parameter values, and the application’s reason when supplied. For a request no operation catalog describes (such as a custom API), it lists every value the agent sends, by location (body.…, query.…, header.…), exactly as sent — Alter’s own credential is never part of that request and is never shown; only the slot Alter fills with it and the Authorization/Proxy-Authorization/Cookie headers are listed by name. When a condition of the approval policy could not be evaluated, or a value it could depend on could not be determined, the page also says which and why. It shows the values the request carries as it sent them (percent-encoding decoded). For a Google Calendar event these are the calendar, the listed guests, attendeesOmitted, start and end with their time zones, recurrence, and the sendUpdates and sendNotifications settings. A move shows its source calendar and destination. Every Google Calendar request also lists its query and body as sent, field by field, so values the policy does not evaluate (an event’s status, title or visibility, each guest’s response and comment, a watch channel’s address, quick-add text) are shown too. A sharing rule shows the rule id it changes, its role and its scope. Values outside the request, such as an event’s current guests, are not shown, and the page says so. Each listed address is checked against the policy’s addresses, and the result is shown next to it; an address with non-ASCII characters is marked, and an address the policy could not judge (the grantee of a sharing rule whose id cannot be read) is shown as not judged. The Wallet never displays response bodies or Alter’s credential. When the values cannot be shown, approval is disabled and the page says why: a temporary fault (retry later), a held request that is missing or failed its integrity check, or a request with a value that cannot be shown faithfully (the page names the field). A Wallet tab opened before a deploy shows a request it cannot fully display as unavailable: the approver can deny it, or reload to review it.
Trust model
Section titled “Trust model”Three properties matter:
- The Wallet only shows what’s already true on the backend. Every Wallet action — viewing, revoking, delegating, and authoring policies — reads and writes the same grant table and audit trail the SDK uses. There’s no “Wallet-side state” that could drift.
- Revocation is immediate. The next
app.request()against a revoked grant raisesGrantRevokedError. If other active grants share the same provider credential, they remain usable; the Vault token is removed when no active sibling grant still needs it. - The Wallet session is app-scoped and separate from the application’s own session. Signing out clears the Wallet session. When the configured provider supports RP-initiated logout, the sign-out flow can also continue through the provider’s end-session endpoint.
When to suppress the Wallet
Section titled “When to suppress the Wallet”For internal admin tools and operator-only apps with no end users, there is no Wallet identity to sign in. Apps with end users can link to the app-scoped Wallet even when they also provide an in-product revocation UI. Building that UI via app.list_grants / app.revoke_grant supplements the hosted Wallet rather than changing its scope.