arkushHelp

For organizations

Administer an instance

This guide is for the admin of an arkush instance, which is most often an org install. Each section covers one task: what the admin changes in the app, what the operator changes in the environment file, and what the app shows when nothing is configured.

On arkush.app, the admins are the people who run arkush.app. A person who signs in there holds no admin right, and the Administration areas do not show.

Two roles share an instance. The admin works inside the app, in Administration. The operator runs the service: the host, the environment file, and the files beside the database. One person can hold both roles.

Before you start

The admin right comes from ARKUSH_ADMINS in the environment file. A person who signs in with an address on that list has three ways in:

Administration is divided into areas, one per job. A panel on the left lists them, and each one has its own address. An area holds one or more sections. For example, the Access area holds a Rights section and a Groups section.

Open /admin itself for the index. On it, you see each problem on the instance that needs attention, with a button to the area where you fix it. When nothing needs attention, the index says so. Each area's page opens with one line that says what it holds. A problem shows in short form: point at the disk bar to read the free space and the fix, and select the (i) beside No security contact to read the full message.

The Administration index, two parts marked with numbers. 1 marks the panel on the left that lists the areas. 2 marks a banner of three problems, each with the button to its area: Disk, an amber bar of the space used and '7% free', with Open Storage; a warning glyph and 'No security contact' with an (i) beside it, with Open Appearance; 2 datasources have no service account, with Open Credentials.
The Administration index: (1) the panel of areas, (2) the problems that need attention, each with the button to the area that fixes it.

In the app, the admin changes what changes often: group membership, the service accounts, the destinations, the pages, and the instance's name. The operator sets who holds power and where the service reads from, in the environment file: the rights, sign-in, the service's own Google credential, and the file locations.

A change in the app applies at once. The service reads the environment file only when it starts, so a changed variable applies after the operator recreates the container.

Give a person a right

Two rights sit above ordinary use, and a person who builds dashboards needs neither. The admin right manages the instance. The analyst right curates the theme library, the instance fonts and the datasource library, sets the Official stamp, and sends a delivery with Send now. It also reads a private sheet or file with the service's own Google account.

Neither right reaches the warehouse. Google Cloud decides who may run a query under a service account (Register service accounts).

In the app

The Access area shows who holds each right. It does not edit them. With a group entry in an allowlist, you make the everyday change in the app: every member of the group holds the right.

  1. Open Administration, then Access.
  2. Under Rights, find a group entry in the allowlist, such as group:analysts.
  3. In Groups, add the person to that group, or remove the person.

The right follows the membership at once. A group that an allowlist names carries a grants admin or grants analyst tag on its row.

In the environment file

To give one person a right without a group, ask the operator to add the address. An address in an allowlist applies after the operator recreates the container.

With nothing configured

An unset allowlist means nobody holds the right. Rights reads nobody for analysts. An instance with no admin shows no Administration to anyone.

Read a setting you cannot change here

The operator sets some settings in the environment file. Each one shows in the area whose job it serves, with the variable that sets it and its value on this instance. Sign-in settings are in Access. The warehouse and the outbound hosts are in Credentials. The rest are in Configuration.

The settings show as a table with two columns: Setting, the variable's name, and Value on this server. A value shows a dim dash when the deployment gives the variable no value. Point at the dash to read Not set. A secret reads set, hidden or shows the dim dash, and never shows the value. To change any of them, ask the operator to edit the environment file and recreate the container.

The How people sign in section of the Access area. A table with the columns Setting and Value on this server names one environment variable per row with its value on this instance, such as ARKUSH_IDENTITY with proxy and ARKUSH_SIGNIN_ALLOW with a dim dash for not set. A line under the table says that a change applies after the container is recreated.
The sign-in settings in the Access area. Each row of the table names the variable and its value.

Two kinds of setting have no row. A file location has none: the area that uses the file names its path where you meet it. A setting with its own control in Administration, such as the two rights, the groups backend or the upload quota, shows in that control instead.

Find who changed access

The audit trail lists every admin act and every access change on this instance, newest first. An access change is a share added, changed or removed on a dashboard, a file or a shared datasource, a dashboard created already shared, and an agent a person connects. Sign-ins are not in the trail. You need the admin right.

In the app

  1. Open Administration, then Configuration, and find Audit trail.
  2. To narrow the list, type a person's address, pick an act, or both, and select Show.
  3. To read further back, select Show older rows.

Each row names who acted, on whom or on what, what changed, and when. A deleted account reads as Deleted account.

In the environment file

ARKUSH_AUDIT_MONTHS sets how many months the trail keeps a row. Only the operator changes it, because the trail records the acts of the admins.

With nothing set

The trail keeps a row for 13 months.

Find what uses the disk

The Storage area shows how much free space the disk of this instance has, how much each part of the instance uses, and how much each dashboard uses. The server reads the sizes when you open the area. You need the admin right.

In the app

  1. Open Administration, then Storage.
  2. Read the free space at the top: Disk, a bar of the space used, and the free share, such as "8% free". The bar turns amber when the disk is low. Point at the bar to read the free space and the total size. The table under it shows the database, the snapshot files, the uploaded files, the published copies, the fonts and the backups. Each row has a bar of its share of the total beside its size.
  3. To find the largest dashboards, read the Dashboards table. It lists the dashboards by Total, the sum of Data, History and Published, largest first. To sort by one of those columns or by owner, select its heading.

Data is the dashboard and its snapshots. History is its earlier versions. Published is the copy that a published page serves. A dashboard in the trash shows in trash, and its bytes stay in the table. The server deletes a dashboard for good 30 days after it went to the trash.

The columns get smaller in these ways:

When the disk has less than 10% or less than 2 GB free, the Administration index shows the disk bar with Open Storage. To get space back, ask the owners of the largest dashboards to delete what they no longer need, or ask the operator for a larger disk.

Leftover snapshot files

A refresh that lost to a newer refresh, or a stop of the server during a write, can leave a snapshot file that nothing uses. The area counts these files and deletes nothing. When the number grows, tell the operator.

Find why something failed

The Errors area shows what went wrong on this instance in the last 14 days: a request the server failed, a scheduled refresh or send that failed, and an agent call that was refused. It keeps the newest 5,000 lines. You need the admin right.

In the app

  1. Open Administration, then Errors.
  2. Read the list. The newest line is first. Each line has what went wrong in plain words and how long ago, the event, what failed, the person it concerns, the dashboard, and the reference of the request. To see the exact time, point at the age. To read older lines, select Show older lines at the end of the list.
  3. Read the mark at the start of each line. Fault means that something broke. Refusal means that the instance turned a person or an agent away, as its settings require. You act on a refusal only when that person should have been let in. To see only the faults, select Faults only.
  4. On a refused agent call, read the tool, the dashboard and the account the agent asked for. If you read on the line that the person may not use a service account, and they should, give them the Service Account User role on that account in Google Cloud.
  5. To read what an error code means and who can fix it, select Who can fix this on its line. Its entry in Error messages opens.
  6. When a person reports an error, ask for the reference at the end of their notice, and the time. Type the reference in Reference, then select Find. The list shows only the lines whose reference holds that text.
  7. If no line has the reference, check the reference. A line older than 14 days, or older than the newest 5,000 lines, is no longer in the list. Then give the operator the reference and the time. The operator searches the log output for the reference.
  8. To see every line again, clear Reference and select Find.

When a problem is still failing, the Administration index shows how many with a button to the Errors area. A failure that repeats counts once, and it stops counting when the item works again. A refused sign-in or a refused agent call is in the list and is not counted.

In the list, a person shows as their email address. A person whose account was deleted, or who never signed in, shows as a pseudonym. See Find a person in the logs.

See who uses the instance

The Usage area in Administration shows how many people use the instance, how they use it, which dashboards they read, and which refreshes cost most. It holds counts only, and never a name. You need the admin right (Before you start).

The counts come from the usage record. The record exists only on an org install where the operator, the person who runs the server, turned usage analytics on. It starts on that day and keeps the number of months the operator set. When usage analytics is off, the Usage area says so.

In the app

  1. Open Administration, then Usage.
  2. In Range, select 7, 30 or 90 days, or the whole record. Each count and each chart on the page shows that range.
  3. Read the sections: active and new people, where the use comes from (the browser, AI agents, and scheduled refreshes and sends), whether new people stay, the most-read dashboards, the dashboards nobody opened in 90 days, and the costly refreshes. To read what a section counts, point at the (i) beside its heading.
  4. To count days in your organization's time zone, select the zone in Reporting time zone at the end of the page, then select Save. The counts on the page move to that zone's days. The zone also applies to the Last active column in Users and to the reader counts of every dashboard.
  5. To read the page in another zone without a change for anyone else, select the zone in Show in time zone, beside Range.

A count of fewer than 3 people shows as a dim "<3", so a dashboard with one reader does not show who that reader is. The Last active column in Users shows the last day each person did something. The owner of a dashboard sees Readers this week in Dashboard settings.

In Which agent apps people use, you see each AI agent app with its calls, the people who used it in the range, and the people who have it connected now. A hosted app, such as Claude or ChatGPT, has its own name there. An agent on a person's own computer has the name that the agent claims, with "(local)" after it, such as "Codex (local)". Arkush cannot check that name. People whose app the Agent apps setting refuses are not in the connected count. Their number is beside it, as stopped.

To build your own charts on the record:

  1. On a dashboard, open the Data workspace from the icon rail at the right edge of the screen, and select New datasource.
  2. Select Instance usage as the source.
  3. Write the SQL over the views that the form lists, such as active_people or dashboard_engagement. The form lists each view's columns.
  4. Refresh the datasource. Its rows show in the Data workspace.

Only an admin can add or refresh that datasource. An agent can then build charts on its rows. The datasource holds counts only, so you can share the dashboard like any other.

With nothing set

The Usage area says that usage analytics is off. Ask the operator to set ARKUSH_USAGE_MONTHS, with the steps in the install guide's section Turn on usage analytics. Tell the organization's people before it goes on, because the record is about them.

Let partners sign in as guests

A member is a person at one of the organization's own domains. A guest is any other person who can sign in, such as a person at a partner company. A guest sees only what someone shares with them, directly or through a group. A dashboard, a datasource-library entry or an uploaded file that is open to everyone stays hidden from guests.

A guest can build dashboards and share their own. A guest cannot change who can view a dashboard that another person owns, cannot open anything to everyone, and cannot publish.

Before you start

In the app

  1. Open Administration, then Access, and find Settings.
  2. In Member domains, type the organization's own domains, such as example.org, and press Enter. Leave the partner's domain out: a person at a domain that is not on this list is a guest.
  3. In Other members, type the addresses of members whose address is at another domain, such as a contractor's personal address, and the names of groups from Groups. If your own address is not at a member domain, add it here, or the save is refused.
  4. To let only some people at a domain sign in, find the switch Only listed people at and the domain. There is one switch for each domain on the sign-in allowlist and each member domain, the partner's domain included. Turn it on, then type the addresses in People at and the domain who can sign in, under it.
  5. Select Save.
  6. Open Appearance, and in Organization name, type the name that people know the organization by. Select Save.

When the save worked, the Share panel has Everyone at and the organization name in place of Everyone signed in. In the Users area, each guest's row has the mark guest, from the guest's first sign-in. At a domain you limited to listed people, a person whose address is not on that domain's list is signed out at their next request. You cannot remove your own address from a list. An admin is never a guest, whatever the address, but the save of the member list still asks for your own address in Other members. If another admin saved the access settings after you opened the page, your save is refused: the page loads the stored settings again, and you make your change again.

A guest sees a dashboard only when someone shares it with them. To share one dashboard with a partner person or group, its editor adds them in the Share panel (Share a dashboard). To let a partner see one dashboard that is open to everyone, its editor includes the partner's domain (Members and guests).

In the environment file

Nothing. No variable sets the members. The operator decides who can sign in at all, with the sign-in allowlist, ARKUSH_SIGNIN_ALLOW.

With nothing set

With no member domains, everyone who can sign in is a member, and nobody is a guest. A public deployment has no members or guests.

Limit agents, downloads, open sharing and self-deletion

With the access settings, an admin decides what people on this instance may do: connect an agent and from which apps, download or export data, open a dashboard to everyone signed in, and delete their own account. Self-deletion starts off, and every other setting starts at the widest value. An admin changes them in the app. No environment variable sets them, and they apply with no restart.

The agent setting and the rows setting can take a list of named people and groups. An entry is an email address or a group, written group:<name>. To manage those groups, see Manage groups.

In the app

  1. Open Administration, then Access, and find Settings.
  2. In Connect an agent, choose who may connect one. An agent acts as the person who approved it, and reads nothing that person cannot read.
  3. In Agent apps, choose Any app, or choose Only the apps below. Then select each app that may connect, select Agents on a person's own computer to allow Claude Code and other local agents, and type the host of any other app, such as agent.example.org, and press Enter. An agent from another app gets a refusal that names the apps you allowed.
  4. In Download or export data, choose who may take rows off the instance. This covers the CSV download, the export of an open dashboard, a copy of a dashboard, the tables in a subscription, and how many rows an agent's SQL preview has.
  5. In Open a dashboard to everyone signed in (or to everyone at the organization, where the instance has members), choose Every editor or Admins only. This covers dashboards, datasource-library entries and uploaded files. Where the instance publishes to the internet, the admin also decides with this choice who may publish: with Every editor, each owner can publish their own dashboard. With Admins only, only an admin who owns a dashboard can publish it, and only admins can use Transfer ownership, so an owner cannot hand a dashboard to another person.
  6. Select People may delete their own account to let each person delete their account from the Your data section of their Settings page. While the box is clear, that section names the contact address of this server for the request, and an admin deletes the account from Users.
  7. If you chose Named people and groups, add each entry.
  8. Select Save.
Limit who may connect an agent to one group. Enter adds the entry, and Save applies it.

The settings apply to the next request. A person the agent setting refuses loses their agents at the next call, and their connection stops with a message naming an admin. A person the rows setting refuses stops seeing Data as CSV, and their export of a dashboard writes the structure with no rows in it. Their copy of a dashboard or of a shared datasource, in the app or through an agent, also carries no rows. An agent from an app you no longer allow stops at its next call, and its row in the person's Connected agents list reads Stopped. Allow the app again, and the agent works again with no new approval. Every change writes one audit line.

What the agent apps setting does not do

In the setting, an app is the address that its sign-in returns to, such as claude.ai. That address is the same for every account of the app: a person with a personal Claude account returns through the same address as a person on your company's plan. To keep agents to the company's plan, limit the connector in that app's own admin settings too, and cover personal accounts in your company's policy. Local agents cannot be told apart either, because any program on a computer can claim to be Claude Code.

What the rows setting does not do

A viewer's browser holds every row of every snapshot, because the dashboard draws and filters from those rows. The rows setting hides the acts that write a file. It cannot keep the rows out of the browser, and a table block still shows them. The two controls that do hold are who may view a dashboard, and what the dashboard's SQL selects: the readers of a dashboard built on totals get only totals.

With nothing set

Everyone signed in may connect an agent from any app, every viewer may download or export data, and every editor may open a dashboard to everyone signed in.

If anyone can sign in to this instance, only an admin shares a dashboard, opens it to everyone signed in, or transfers its ownership, whatever the sharing setting says. Everyone else keeps their dashboards private, so no person meets a stranger's email address.

Publishing to the internet is off until the operator sets ARKUSH_ALLOW_PUBLISHING=true in the instance's environment. The Access area reports the switch. With it off, nobody publishes, the Share panel shows no publish section, and every published address answers nothing — including one published before the switch went off. With it on, the sharing choice above decides who may publish, and only a dashboard's owner publishes it. Any editor can unpublish, whatever the switch and the setting say.

To take down a published dashboard that you cannot edit, select it with Select on the Dashboards page and close it to private. That deletes the published copy. Access lists every published dashboard. Moving a published dashboard to the trash unpublishes it too, and restoring it does not publish it again.

Manage groups

A group is a named set of people. A person can share a dashboard with a group, and an allowlist can name one. The instance reads membership from one of two backends. You see which one in the section heading: Groups for the membership file that admins edit, and Google Groups for the Google Workspace directory.

In the app: Groups

  1. Open Administration, then Access, and find Groups.
  2. Select Add group….
  3. Type a short name in lowercase, such as finance. A name holds no space, : or @.
  4. Type or paste addresses into Add members, then press Enter.
  5. Select Add group.
Add a group: type its name, paste the addresses, press Enter, then select Add group.

To change a group, select Edit on its row. Remove a member with the close button on the member's chip, add members the same way, and select Save members. The editor marks a member that the instance has never seen — no sign-in, no dashboard, no share, no other group. When you see the mark, check the address for a typo. The mark does not stop the save.

Delete removes a group after a dialog that counts the dashboards shared with it. Shares and allowlist entries that name the group then match nobody.

In the app: Google Groups

  1. Open Administration, then Access, and find Google Groups.
  2. Select Add group….
  3. Type the group's address, such as team@example.org.
  4. Select Add group. The service checks the address against the directory first.

Membership shows read-only. Change who is in a group in Google. After Remove, this instance no longer reads the group, and the group stays in Google.

In the environment file

The google backend also needs a grant outside the file. The service's own identity needs the Groups Reader admin role, in the Google Workspace Admin console.

With nothing configured

Groups work with no setting. A new instance shows an empty Groups section, and the first group an admin adds creates the file. On the Google backend, a group that Google has not answered for yet lists no members.

Register service accounts

A BigQuery datasource that runs on the server names a registered service account in Runs as. The service impersonates that account, so no key is stored anywhere, unless the operator gave the account a key file. The admin keeps the registry, and the operator gives the service its credential. Whoever manages IAM in Google Cloud decides who may use each account.

In the app

  1. Open Administration, then Credentials.
  2. Select Register account….
  3. Type the account's address, such as reports@PROJECT.iam.gserviceaccount.com.
  4. In Label, say what the account is for.
  5. Select Register account.
  6. Select Verify on the new row.
Register an account, then verify it. On a server with no server-side BigQuery, Verify names the missing variable.

Verify makes two checks, and you read the result of each on its own line. For the first line, the service asks Google for a real token for the account. For the second line, the service makes a dry run of SELECT 1 in the billing project as the account, which reads no table and bills nothing. This check proves that the account holds BigQuery Job User there. A line that fails has the cause. If a gcloud command fixes that cause, the line has the command too. For an account that only database datasources name, the second line is a note, not a failure.

Remove takes an account out of the registry after a dialog. Datasources that name the account keep their data, but their next run refuses and their schedules pause. You cannot remove an account with a key file: ask the operator to take the key file away first.

Choose who may use an account with a key file

On an organization's own install, the operator can give an account a key file on the server. The service then runs that account from its key, and an admin decides in the app who may use it, with the account's list. Google Cloud's grants on the account have no effect. The operator sets the key file, and an admin keeps the list. You cannot change the key file in the app. The list is empty when the operator adds the key, and while the list is empty, nobody can use the account.

The account must be registered first: it has a row in Administration → Credentials once an admin registers it (Register service accounts). The operator then adds the key file to that registered account. If you see no row for the account, register it, and tell the operator.

Open Administration, then Credentials. Under the account's row, you see:

To change who may use the account:

  1. Select Edit list under the account's row.
  2. Type who may use it, separated by commas or new lines: an address, such as ana@example.org, or a group from Groups by its short name, such as finance. On an instance that uses Google Groups, a group's name is its address, such as finance@example.org. Type * alone for everyone who can sign in.
  3. Select Save list.

If the save is refused, the message has the reason. Fix the list, and select Save list again.

The row then has the list you saved. A person on the list sees the account in Runs as after they reload the app. A person you take off the list can no longer run as the account: their next run under it refuses, and a schedule that rests on their last run pauses at its next run. Each change has a line in the audit trail.

Datasources without an account

This section appears only while a BigQuery datasource names no service account. Such a datasource cannot run on the server, and its schedule is paused. Each row opens the dashboard's or the library entry's details page.

The fix is Runs as: in the dashboard's Data workspace, or on the entry's details page. A person who can edit the dashboard, or manage the entry, sets it. The section disappears when the list is empty.

In the environment file

In Google Cloud

For an account without a key file, the grants that let a person use it are in Google Cloud, never in arkush. Whoever manages IAM on the account's project makes these grants:

With nothing configured

Every instance has the registry. Empty, the section reads "No service accounts registered yet.", and nothing runs as a service account. With no ARKUSH_BQ_PROJECT, the Server-side BigQuery row in Configuration reads not configured — people query with their own Google accounts. Verify then names the variable.

Set how long a BigQuery query may run

The query time limit is how long one BigQuery query runs before arkush cancels it in BigQuery. The limit covers every BigQuery query on the instance: a person's own query in the browser, and a query on the server from the app, an agent or a schedule. A cancelled query stops billing. The person who ran it reads a message that names the limit and asks them to narrow the query or to ask an admin.

You need the admin right.

In the app

  1. Open Administration, then Credentials, and find Query time limit.
  2. In Minutes, type a whole number from 1 to 60.
  3. Select Save.

The next query uses the new limit. A person whose page was open before the change gets the new limit when they reload the page. If the value is out of range, the save fails, and the message names the range.

A query from the app that runs on the server keeps its request open until the query ends. If a proxy in front of the server closes long requests sooner, the person sees an error, and the query goes on. When it ends, the rows reach the dashboard without a reload.

In the environment file

Nothing. No variable sets the limit.

With nothing set

A query runs for at most 5 minutes.

See every schedule and whether it runs on time

A dashboard or a shared datasource can refresh its data on a schedule, and each one is set up on its own page. In the Schedules area, you see every scheduled refresh on the instance in one list, with the datasources that fail.

In the app

  1. Open Administration, then Schedules.
  2. Read Scheduled refresh. Each row names the dashboard or shared datasource, its schedule, its owner, and how its datasources stand: on time, retrying, stopped, or stopped retrying.
  3. To see what the schedule did, open Last runs on the row. Each run shows when it ran, whether the schedule or a refresh trigger started it, and what it saved or why it failed.

A scheduled run that fails retries after 5, 10, 20, 40 and 80 minutes. When the last retry fails, the schedule stops retrying that datasource, and the owner gets an inbox entry. The schedule starts again when someone runs the datasource once: Refresh in the app, an agent, or the refresh trigger. Deliveries and subscriptions follow the same rule, and a person who selects Send now starts them again at once. For a delivery, an analyst can also start it again with Confirm changes, at its next scheduled time.

With nothing set

No dashboard refreshes on a schedule, and the list says so.

See what leaves on a schedule

A delivery is a dashboard's charts, scorecards and tables, sent to a Slack channel, a list of email addresses, or a webhook on a schedule. Each one is set up on its own dashboard. In the Schedules area, you see every delivery on the instance, grouped by the destination it posts to.

In the app

  1. Open Administration, then Schedules.
  2. Read What leaves on a schedule. Each destination lists the dashboards that send to it, with the schedule, who blessed it, and how the last send went.
  3. To see each send the schedule made, open Last runs on the delivery.
  4. To see a delivery's message and blocks, select the dashboard's name.

A delivery marked not approved — never sends is set up but inactive. A delivery goes out only after an analyst approves it on that dashboard: with Confirm changes, where the analyst sees the message and nothing is posted, or with Send now, which posts it at once. An analyst who loses the analyst right, or loses edit access to the dashboard, stops every delivery they approved. A delivery also stops when a datasource's rows no longer match the run that produced them, because someone wrote rows into the dashboard after the run. One authorized run of each affected datasource starts the delivery again.

Before you remove a destination

Each destination in the registry below lists the dashboards it serves. When you remove the entry, every one of them stops at the next schedule, and the dashboards themselves have no sign of it. Read that line first.

With nothing set

No dashboard sends anything, and the list says so.

Add delivery destinations

A destination is a named place that deliveries send to: a Slack channel, a list of email addresses, or a webhook. A dashboard holds only the destination's name, never its token, its address or its recipients. You see those only in the Destinations section.

Before you start

In the app

  1. Open Administration, then Deliveries.
  2. Under Destinations, select Add a destination….
  3. Pick the Kind: Slack, Email or Webhook.
  4. Type a Name. Dashboards name the destination by it, and you cannot change it later.
  5. Fill in the fields of the kind:
    • Slack: pick the Channel from the channels the bot is in. If the bot cannot list its channels, type the Channel ID, such as C0123456789: in Slack, it is at the bottom of the channel's details. The channel name does not work.
    • Email: the Recipients, and a Sender if needed.
    • Webhook: the https Address and the Signing secret, and a Bearer token if the receiver checks one.
  6. Select Add destination.
  7. If an email address is outside the people who can sign in here, the app names it and asks once. Select Save addresses to send reports there, or cancel and remove it.

The destination shows as a row in the list, with the dashboards it serves. To change a destination, select Edit on its row. A stored token or secret reads Set, and the app never shows it again. Select Replace to type a new one. If you change a webhook's address, type its secret again: a stored secret never goes to a new address.

The Slack bot section shows a mark for each feature: a check where it works, and a warning where the bot token lacks a scope. Point at a mark, or select the (i), to read the scopes. The features are:

A missing scope does not stop a save, because a token without the direct-message scopes still posts to its channels. Features that need none of the missing scopes keep working. To add a missing scope:

  1. Ask a Slack workspace admin to open the Slack app on api.slack.com/apps.
  2. Add the scope under OAuth & Permissions, in Bot Token Scopes.
  3. Select Reinstall to Workspace.
  4. If Slack then shows a new bot token, give it to the operator, who sets it in the environment file and restarts the service.
One Slack destination added in the form.

The operator can also edit the registry as a file: select Edit the file. The file shows each secret as ••••••••. Leave a masked value as it is to keep the stored secret, or type over it to set a new one. The service checks the file before it writes. An invalid file refuses with the problem named, and the stored file stays as it was. If the file changed after it loaded, the save refuses too: select Reload and make the edit again.

Subscriptions send a dashboard to one person. With the Slack bot set, each person gets it as a Slack direct message. The bot needs four scopes: chat:write and files:write to post, and users:read.email and im:write to find each person and open the direct message.

To send subscriptions by email or to a webhook instead, select Edit on that destination's row, select This is the subscription channel, and save. On an email destination, each person gets the mail at their sign-in address. On a webhook, the body names the person, and the receiver routes it. Only one destination carries the mark, so it moves from any other destination.

In the environment file

With nothing configured

Every instance has the registry. Empty, the list says that nothing is delivered anywhere, and the Scheduled sends flyout offers no Deliver…. An admin reads that channels are added here. Everyone else reads that the server has no channel to post to. Without the Slack bot, the Slack bot section names the setting, and a Slack destination cannot be added. Without the Slack bot and without a destination marked for subscriptions, the subscription part of the flyout does the same: an admin reads the setup step, and everyone else reads that the server cannot send subscriptions.

Send people their inbox by email

With inbox email on, each person gets an email when an entry in their inbox stays unread for 15 minutes. Entries that arrive together come in one email. Each person chooses in their own Settings what they get. By default they get email only when something broke or needs them: a refresh or a send that stopped, and a dashboard in the trash. The email names the dashboard, what happened and the people involved. It never holds the text of a comment.

Before you start

In the app

  1. Open Administration, then Deliveries.
  2. In Inbox messages, tick Email people about their inbox.
  3. Select Save.

The section then says how many people got an inbox email in the last 24 hours. Right after you turn email on, it says that nobody got one. Only entries that arrive after you turn email on are sent, so nobody gets a backlog. The first email leaves no sooner than 15 minutes after a new entry. To stop the email, clear the box and save. At most 120 inbox emails leave in an hour, and the rest wait for a later sweep.

Each person chooses what they get in their own Settings, under Notifications: a table with a row per category and a column per channel.

Send the inbox in Slack too

People can also get their unread entries as a Slack direct message, from the instance's Slack bot. Every Slack box starts off, so a person gets nothing in Slack until they tick it in the Slack column of Settings, under Notifications. The Slack switch does not need the mail relay.

  1. Make sure that the Slack bot is set. See Add delivery destinations. The bot needs the users:read.email and im:write scopes. A Slack workspace admin adds them in the settings of the Slack app, on the OAuth & Permissions page, and installs the app again. Until the bot is set, the Inbox messages section says that no Slack bot is set, and it shows no Slack switch.
  2. In Inbox messages, tick Send people their inbox in Slack.
  3. Select Save.

The first message to a person finds their Slack member by their email address. If Slack has no member at that address, no message reaches the person. The person then selects Subscribe on any dashboard and pastes their member ID once when the panel asks for it. The member ID is in their Slack profile, under ⋮ → Copy member ID. If a bot scope is missing, the subscriptions of a person show the error in their list, and the operator sees the failure in the log.

With nothing set

Inbox messages are off after an install and after an upgrade. Each person's Settings says that this server sends no messages about the inbox, and the inbox in the app shows every entry.

Get a notice when Slack deactivates someone

When a person leaves, their subscriptions, the deliveries they approved as an analyst, the scheduled refreshes that run as them, and their agents keep running until an admin suspends the account. Where the Slack bot is set, Arkush asks Slack once a day about each person who has such work. When Slack deactivates one of them, every admin gets an Admin notice in the Inbox. It names the person and what runs in their name.

Before you start

When the alert runs, the line at the top of the Users area says that every admin gets an Inbox notice when Slack deactivates someone with work in their name.

When a notice arrives

  1. In the Inbox, select the person's address on the notice.
  2. The Users area opens on the person's row. Select Suspend, then confirm. Suspend stops everything that runs in their name. See Suspend an account.
  3. Do the rest of Offboard a person: transfer their dashboards as Transfer a dashboard or recover access shows, then delete the account.

Arkush never suspends anyone by itself. The notice resolves at the next sweep after one of these: nothing runs in the person's name any more, a suspension included, or Slack reactivates the person.

If the person has not left, for example after a move to another Slack workspace, check with the person or their team. Then select Done in the menu of the notice. The notice stays done until Slack's answer about the person changes again.

With nothing set

Without the Slack bot, no notice comes. The Users area says that departure alerts are off and names the setting the operator sets.

See who joined the waitlist

An instance where anyone can sign in keeps a waitlist for Arkush for organizations. Where a feature is missing, the app says the feature is available in Arkush for organizations and links to the Arkush for organizations page. A signed-in person joins there. The entry stores the person's email address, the date, the features that brought them, and what they wrote about themself.

In the app

  1. Open Administration, then Users.
  2. Read Waitlist. Each person shows with the date, the features that brought them and what they wrote. A count per feature sits above the list.

A person leaves the list from the Arkush for organizations page. Delete account removes the entry too, and the server deletes an entry 12 months after the person joined.

With nothing set

No setting turns the waitlist on or off. An instance that limits who signs in keeps no waitlist, and each feature keeps the line it shows where the feature is not set up. The section shows here only when the list holds entries from a time anyone could sign in.

Set the instance identity

The instance identity is the instance's name, logo and security contact. Everyone who opens the app sees the name in the toolbar and the browser tab, and the logo in the toolbar. The landing page, the legal pages and the About page use the name too.

In the app

  1. Open Administration, then Appearance, and find Instance identity.
  2. In Name, type the instance's name.
  3. In Organization name, type the organization's name. Where the instance has members, the Share panel has Everyone at and this name. Blank uses the instance's name.
  4. In Logo, type the https address of an image.
  5. In Security contact, type an email address or an https page, such as security@example.org.
  6. Select Save.
Set the name, the logo and the security contact, then select Save.

With a logo, the toolbar shows the logo and uses the name as its alternative text. The service publishes the security contact at /.well-known/security.txt, where a security researcher looks for it. Every published dashboard's page also carries Report this page, which sends its reader to the same contact. With no contact set, a published page has no report link. While publishing is on, the Administration index then shows a warning glyph and No security contact, with an Open Appearance button. The (i) beside the warning holds the full message.

In the environment file

Nothing. No variable sets the identity. The old variables ARKUSH_INSTANCE_NAME, ARKUSH_LOGO_URL and ARKUSH_SECURITY_CONTACT stop the service at start, with a message naming Appearance, where the identity is set.

With nothing set

The toolbar says "arkush" alone, and the instance publishes no security.txt.

Choose the default theme

Every new dashboard starts with the default theme, in the app and from an agent. With a theme that has a light and a dark face, each viewer sees the face for their mode. Dashboards that exist keep their own theme.

In the app

  1. Open Administration, then Appearance, and find Default theme.
  2. In Theme for new dashboards, pick a theme.

The pick saves at once. The list offers the house theme, the built-in themes, and the saved themes of the theme library. An analyst saves a theme to the library from the theme editor.

A server can hold a different theme for each mode from an earlier version. The list then reads Per mode with the two themes, and new dashboards take the theme for their creator's mode. A dashboard that an agent creates takes the light one. Pick one theme to replace both.

In the environment file

Nothing. No variable sets the default theme.

With nothing set

New dashboards take the house theme, Arkush, in a light face and a dark face. A pick saved as Arkush Light or Arkush Dark in an earlier version means Arkush too, and a pick of one face of a built-in theme means that whole theme. Pick Classic for the plain look the app draws without a theme. A pick whose saved theme was deleted reads Missing theme — house theme applies.

Write the instance pages

The instance pages carry the instance's own words: the landing copy, the examples page, the privacy policy, the terms of service, and the agent context. Each page is one markdown file. A privacy policy names who holds the data on this instance, so the software ships the editor and no words.

In the app

  1. Open Administration, then Pages.
  2. In the Page row of segments, select Landing page, Examples, Privacy policy, Terms of service or Agent context. Examples shows only on an instance that publishes dashboards to the internet.
  3. Write the page in markdown.
  4. Select the save button, such as Save privacy policy.
  5. Open the page in a new tab and read the result.
Pick a page, write it in markdown, then select the save button that names the page.

The landing copy replaces the headline and the paragraph under it, between the instance name and the sign-in buttons. The buttons and the agent setup stay. A paragraph that holds only ![description](link) shows a picture, or a YouTube or Vimeo video.

The service publishes the privacy policy at /privacy and the terms at /terms. The landing page links each one that has words. The pages take headings, paragraphs, lists, links, bold, italics and code. Raw HTML shows as plain text.

The examples page shows visitors the dashboards you chose, at /examples. The landing page links it from the top bar and beside the sign-in buttons. To add a dashboard, publish it first, then link its published address and say in one line what it shows. A paragraph that holds only ![description](link) shows a picture, such as a preview of the dashboard. The examples page plays no video.

The Agent context page is for agents, not for people. Every agent that authors on this instance reads it as a part of the authoring guide, so write the tables agents should use, the names your team gives to metrics, and your house rules. Leave out anything secret, any credential and any personal data: every agent reads the page, and the text reaches each agent's model vendor. The page holds up to 20 KB. An analyst edits it, and an admin who is not an analyst cannot.

If the file changed after it loaded, the save refuses: select Reload and make the edit again.

In the environment file

With nothing written

A blank landing page shows the stock copy. A blank examples page, privacy policy or terms do not exist: the address answers not found, and nothing links to it. If the service cannot read or write a file, the section shows the error with the file's path and its variable. The operator fixes the path.

Arrange the landing page

In the landing layout, you choose which sections the landing page has and which agents it has steps for. The agent tabs also set the list on each person's Settings page, under Connected agents. You need the admin right.

  1. Open Administration, then Pages.
  2. Under Landing layout, select Show the story or Show the features to show that section. A new instance has neither.
  3. Under Agent tabs, clear a tab to hide it. Select the up and down arrows to change the order.
  4. To give steps for an agent that is not in the list, such as your company's own, fill in Your own agent tab: a tab name and the steps, one per line.
  5. Select Save landing layout.
  6. Open the landing page in a new tab and read the result.

A tab that the Agent apps setting in Access refuses is greyed, and the page and the Settings list do not have it, whatever you choose here. To show it, allow its app in Access first. Your own tab is never hidden by that setting, so add your agent's host under Agent apps too, or the agent cannot connect.

Review the people on the instance

The Users area has a row for every person who appears on the instance: in sign-ins, dashboards, shares, agents and groups. It stores nothing of its own. Each row counts the person's agents, dashboards, shared datasources and uploaded storage, and has their rights and groups.

In the Rights column, each right shows as a glyph: a shield for admin and a grid for analyst. Each group the person belongs to shows as the people glyph and the group's name. Point at a glyph to read Admin, Analyst or Group. A person with no right and no group reads signed in.

In the app

  1. Open Administration, then Users.
  2. Search by email or by log pseudonym, or sort by dashboards owned, storage used or agents connected.
  3. Select a person's email to open the row.
Search for a person, then select the email to open the row.

The open row starts with Copy email, which copies the person's address for a grant or a group. Under it, the row lists the person's onboarding answers, dashboards, shares, shared datasources, uploaded files, subscriptions and connected agents. Each dashboard under Shared with them shows the role as an eye or a pencil, and the initials of its owner. Point at them to read the words. Remove all N shares… removes every share that names the person, after one dialog. With one share, the button reads Remove the share…. Remove on a subscription stops its sends after a dialog. When a person leaves, the row is where Offboard a person starts.

Find a person in the logs

The service's logs never hold an email address. Each line names a person by a pseudonym, for example u_4cd3a619b5290108, which stays the same for that person on this instance. The open row of a person shows their pseudonym. To find who a pseudonym in a log line belongs to, type it in the search field.

When someone reports an error, ask for the reference at the end of their notice, and the time. Look up the reference in the Errors area first. See Find why something failed. If no line matches, give the operator the reference, the time and the person's pseudonym. The operator finds the lines with the steps in the install guide, in the section on reading the logs.

In the environment file

With nothing configured

The Users area needs no setting. A new instance lists nobody until someone signs in. An unset quota reads no limit.

Transfer a dashboard or recover access

An admin sees every dashboard's title, owner and dates. To open a dashboard, the admin still needs a share. The acts below reach any dashboard. Each act shows in the dashboard's own sharing list or version history, where the owner sees it.

In the app: one dashboard

  1. Open Administration, then Users, and open the owner's row.
  2. Under Dashboards they own, find the dashboard. Its row shows its acts as buttons.
  3. Select Grant me edit access… or Transfer ownership….
  4. For a transfer, type the new owner's email and select Transfer ownership.
  5. Read the dialog and confirm.
Transfer one dashboard from its owner's row. In the dialog, you read what changes before you confirm.

In the app: several dashboards

  1. Open Dashboards — the instance's dashboard list, in the section links at the top, outside Administration.
  2. Select the Whole instance tab.
  3. Select Select and tick the dashboards.
  4. In the bar, select Share…, Remove access…, Who can view, or More and then Transfer ownership….
  5. Read the dialog and confirm.

In this tab, the Access filter on the dashboard list has the choice No owner recorded. This filter is on the dashboard list, not in the Access area of Administration. With it, you find the dashboards that nobody owns, which only an admin can reach. Transfer each one to a new owner.

In the environment file

Nothing. These acts work on every instance.

Revoke agent grants

A grant lets an AI agent act as the person who approved it. The agent reaches the dashboards that person reaches, and each change it makes carries that person's name. A person disconnects their own agents in the Connected agents section of their Settings page. An admin sees and revokes every grant.

In the app

  1. Open Administration, then Users. The Agents column counts each person's grants.
  2. Open the person's row.
  3. Under Connected agents, read each agent's bar: the time left on its approval, with the days left beside it. Point at the bar to read the dates. Select Disconnect on one agent, or Revoke all access….
  4. Read the dialog and confirm.
Part of a person's open row in the Users area. Shared with them lists one dashboard, with an eye for the view role and its owner's initials, and Remove the share… at the right. Connected agents reads that no agents are connected and that Revoke all access still signs out every browser signed in as this account. The Revoke all access… button is at the right.
Connected agents in a person's row. You see Revoke all access even when no agent is connected.

A revoked agent stops at once, and a new connection needs a fresh approval. When the service signs people in itself, Revoke all access also signs out every browser signed in as the person. It deletes the person's passkeys, and every unused sign-in code sent to the person stops working. Revoke all access also removes the person's subscriptions, inbox and the tables they saved for their agents, and takes the person off every access setting that names them. It does not stop a new sign-in: to end the access of a person who leaves, see Offboard a person. Connected agents shows for every person, including a person who connected no agent. For that person, Revoke all access still ends their browser sessions.

In the environment file

No variable turns agents on or off. To limit who may connect one, use the agent setting in Access. When the service signs people in itself, ARKUSH_SIGNIN_ALLOW binds agents too: an address taken off the list stops its agents. A * or @example.org entry does not name a person, so no single address comes off it. There, and behind an identity-aware proxy, Suspend is the cut-off.

Read the onboarding answers and edit the questions

With the onboarding ask, each person gets a few of the instance's own questions once, when they first open the app signed in. A person who first signed in through an agent has a row in Users before that, with no answers yet. From the answers, an admin learns how to set the person up: which group to add them to, which data to share. Only the person and the admins read the answers.

In the app

  1. Open Administration, then Users.
  2. Open a person's row.
  3. Read the answers under About.

Delete account removes the person's answers with the account. A person edits or clears their own answers under About you, in the Profile section of their Settings page. The section shows About you while the instance asks at least one question, or while the person keeps at least one answer.

Edit the questions

  1. Open Administration, then Pages.
  2. Under Onboarding ask, select Add a question…, or Edit on a question or on the intro line.
  3. Write the question and an optional hint.
  4. Select Add question for a new question, or Save question for an edit. For the intro line, select Save.

When the save works, the form closes, and the list shows the question with its new wording. A question you add reaches the people who first sign in after you add it, never the people who already answered or skipped. A question you reword keeps the answers people gave to it, and Users shows those answers under the new wording. Nobody who already answered gets the question again.

The instance asks at most 10 questions. A retired question does not count toward the 10. To stop asking a question, select Retire at the right end of its row, then select Retire question in the dialog. The question stays in the list with the label Retired. The answers people gave to it stay readable under Users, under its wording. To ask a retired question again, select Ask again on its row. While 10 questions are asked, Ask again and Add a question… do nothing until you retire one.

The questions live in the file ask.yml in the state directory, or in the file that ARKUSH_ASK_FILE names, so the operator can also edit them by hand. If the file changed after you opened the page, the save is refused. Then select Reload under the list, or reload the page, and make the edit again. If a hand edit broke the file, the section shows the error, and the operator fixes the file.

With no questions

With no question asked, the ask reaches nobody, and stored answers stay readable. The Users area still lists every sign-in.

Suspend an account

A suspension keeps one address out of the instance until an admin lifts it. The address cannot sign in by any method, and its agents and open sessions stop, whatever the sign-in list admits. The person's dashboards and files stay.

In the app

  1. Open Administration, then Users.
  2. Open the person's row.
  3. Under Account, select Suspend.
  4. Read the dialog and confirm.

Every browser signed in as the person is signed out, their agents and unused sign-in codes stop working, and every dashboard they published is unpublished. A person who tries to sign in, or who opens the app, reads that an admin suspended the account, with the contact address of the instance. The address shows under Suspended accounts at the top of Users. To let the person back in, select Lift suspension there or in their row. Lifting publishes nothing again. You cannot suspend your own address.

Delete an account

Delete account removes a person's account for good. Use it when a person leaves, or when a person asks for the deletion of their account.

In the app

  1. Open Administration, then Users, and open the row.
  2. To keep the person's dashboards, select Transfer all N to… under Dashboards they own and type the new owner.
  3. To keep a copy of the person's data, select Download their data under Account. The browser saves one JSON file.
  4. Under Account, select Delete account.
  5. Read the dialog. It counts the dashboards that still go to the trash, the dashboards other people open, the published addresses that stop answering and the uploaded files. Confirm.

The deletion ends every session, agent, passkey and unused sign-in code of the person. It moves the dashboards the person still owns to the trash for 30 days, with "Deleted account" as their owner. To keep one, restore it from the trash on the Dashboards page and transfer it to a new owner. The deletion also deletes their uploaded files, library datasources, sandboxes, subscriptions, inbox, answers and username. It takes the person off every access setting and group file entry. In other people's dashboards, "Deleted account" replaces the person's address on comments and changes. A suspension of the address stays. You cannot delete your own account here.

Signed-in browsers in the row lists the browsers signed in as the person, with Sign out on each. Use it when a person reports a lost device.

Offboard a person

An account is its email address, so ownership, shares and rights follow the address. When a person leaves, the operator, the admin, and the owners of the person's accounts outside arkush each end one part.

  1. Admin: in Administration → Users, open the person's row and select Suspend under Account. The suspension ends every way in to arkush at once. See Suspend an account.
  2. Operator: where ARKUSH_SIGNIN_ALLOW names the address, remove the address from the list. Behind an identity-aware proxy, block the address at the proxy.
  3. Identity provider: suspend the person's account in the organization's identity provider and mail system, such as Google Workspace.
  4. GitHub: where people sign in with GitHub, remove the person from each organization in ARKUSH_SIGNIN_GITHUB_ORGS.
  5. Operator: remove the address from ARKUSH_ADMINS and ARKUSH_ANALYSTS where it is named.
  6. Admin: under Dashboards they own, select Transfer all N to… and type the new owner.
  7. Admin: ask the editors of a dashboard to adopt any chart they want from the person's sandbox. A sandbox holds the charts one person made over a dashboard they could view, and to adopt a chart copies it into the dashboard. The person's row gives the number of their sandboxes, and each editor sees the sandboxes on their dashboard in its Sandboxes panel. The next step removes the sandboxes.
  8. Admin: under Account, select Delete account. See Delete an account.
  9. Admin: on the Google backend, take the person out of each group in Google. The groups file in Access loses the person with the deletion.
  10. Google Cloud: remove the person's Service Account User role on each service account. Where a Google group holds the role, take the person out of that group instead.

Transfer all N to… shows only for a person who owns more than one dashboard. With one dashboard, use Transfer ownership… on its row.

The published address of a dashboard stays the same after a transfer, so the links people posted keep working. The notice after Transfer all N to… names how many of the transferred dashboards are published. The suspension unpublishes every published dashboard the person still owns, and those addresses stop answering. To keep an address answering with no gap, do the transfer before the suspension. After a suspension, the new owner publishes the dashboard again, and it answers at the same address.

To end the access of a person and keep the account, select Revoke all access… under Connected agents in place of Delete account. Revoke all access ends the sessions, agents, passkeys, unused sign-in codes and subscriptions, and keeps the dashboards, the files and the answers.

The suspension in the first step stops every schedule, delivery and subscription in the person's name at the next sweep. Without a suspension, either of two steps stops a schedule that rests on the person's run, and whichever step you take first takes effect. Removing the address from ARKUSH_SIGNIN_ALLOW pauses every datasource the person blessed. That pause starts at the first sweep after the operator restarts the service with the new list, whatever Google still grants the account. The Google Cloud step pauses the warehouse datasources among them, within an hour.

A Slack delivery that the person approved stops at its next due send. It stops when the person loses the analyst right or edit access to the dashboard, or leaves the sign-in allowlist. Another analyst starts it again with Confirm changes at its next scheduled time, or with Send now at once.

WARNING — Finish every step before the organization gives the address to someone new. The person who gets a reused address also gets what the old account still holds: its dashboards, its shares, its group memberships and its rights.