# Publish internal apps with Private Access

> Put an internal web app behind passkey sign-in at its own address, carried by a connector that dials out from your network. No VPN, no inbound ports.

Source: https://docs.trustaige.com/manage/private-access

Private Access puts an internal web app, such as a wiki, a dashboard or an admin
tool, at its own HTTPS address and lets in only the people in your organization
who sign in with Trustaige. A small connector called Conduit runs on a server
inside your network and dials out to the Trustaige edge, so nothing opens
inbound, and your people install nothing: they open the address in a browser
and sign in with their passkey.

How a request reaches a private app:

1. Conduit → Trustaige edge: dials out and keeps a tunnel open
2. Person → Trustaige edge: opens the app’s address
3. Trustaige edge → Trustaige: sends them to sign in
4. Person ↔ Trustaige: passkey
5. Trustaige edge → Trustaige: may this person reach this app? (asked again every minute)
6. Trustaige edge → Conduit: the request, through the tunnel
7. Conduit → Internal app: the request, with who signed in
8. Internal app → Person: the app answers

## How people reach a private app

Each private app gets an address under `trustaige.app`, made from the app's name
and the first part of your organization's domain. For an app named **Team Wiki**
in an organization whose domain is `example.com`, that's
`https://team-wiki.example.trustaige.app`.

- **Where they find it:** on their **Apps** page in Trustaige, under **Private
  applications**, or by opening the address directly.
- **Signing in:** the address sends them to Trustaige to sign in with their
  passkey, then back to the app.
- **Who gets in:** every active member of your organization until you assign
  groups to the app; once you do, only the members of those groups.
- **When access ends:** the edge asks Trustaige again at least once a minute
  whether the person may still reach the app. Remove them from the group,
  suspend their membership or sign them out of Trustaige, and they lose access
  within a minute.

A private app is never shared with another organization: the hub doesn't offer
sharing for it.

## Before you begin

| You need | Why |
|---|---|
| The **apps:manage** permission | Creating private apps, minting connector tokens and removing connectors all need it. Minting a token and removing a connector may also ask you to confirm it's you with your passkey. |
| A server inside the network that can reach the app | It runs the connector. Linux, macOS and Windows are supported; see [Install the Conduit connector](/manage/conduit). |
| Outbound HTTPS from that server to `edge.trustaige.app` | The connector dials out on port 443. Nothing needs opening inbound. |
| The app's internal address | Where the connector reaches it, such as `http://wiki.internal:3000`. |

## 1. Add the private app

1. Open **Apps**. Under **Private applications**, click **Private app**.
2. Fill in **Name your private app**:
   - **App name**: what people see, such as `Team Wiki`. It also becomes the
     first part of the app's address.
   - **Internal origin URL**: where the connector reaches the app on your
     network, such as `http://wiki.internal:3000`. It must start with `http://`
     or `https://`.
   - **Site**: the network the app lives in. Keep `default` unless you run
     several networks; see [Sites and failover](#sites-and-failover).
   - **Plain identity headers**: turn on only for an app that signs people in
     from trusted proxy headers, such as Grafana's auth proxy, MediaWiki or
     Kibana. See [What the app receives](#what-the-app-receives).
3. Click **Continue**. The hub creates the app and a one-time registration
   token for its site. You may be asked to confirm it's you.

The next step, **Deploy the connector**, shows the address the app will answer
at, under **Commissioning**, the registration token, a download of Conduit for
each platform, and a link to that platform's install steps.

## 2. Run the connector

The token registers one connector for the app's site. Run the connector
yourself, or send the token to whoever runs servers in that network with this
link: [docs.trustaige.com/manage/conduit](/manage/conduit). That page covers
every platform, running it as a service, upgrading and removing it.

> **Important:** The token works once and expires an hour after it's minted. Treat it as a
> secret until it's used: whoever redeems it first adds a connector to your
> network. If it expires, mint a fresh one from **Connectors**.

The hub listens for the connector while you wait: "Listening for the connector".
When the connector dials in, the line reads "Connector *name* is online", with
its operating system, architecture and Conduit version. Click **Continue**.

## 3. Choose who can reach it

The last step says the app is behind Trustaige and gives its address. Click
**Assign groups** to choose who can reach it, or **View app** to do it later
from the app's page. Until you assign a group, every active member of your
organization can reach the app.

## Sites and failover

A site is one network that its connectors can reach. Every connector in a site
can serve every app in that site, so a second connector on a different machine
keeps the apps reachable when the first one's host goes down.

To add a connector, open **Apps → Connectors** and click **Add connector**, or
**Connector** on a site's card. Under **Choose a site**, reuse a site's name to
add failover for the apps already there, or type a new name to start a
separate network. Click **Mint a registration token**, then hand the token on
as in [step 2](#2-run-the-connector).

Each site's card on **Connectors** shows its health:

| Badge | What it means |
|---|---|
| **failover ready** | Two or more connectors, all online. |
| **single connector** | One connector serves the site. If its host goes down, every app there goes with it. |
| **partly offline** | Some of the site's connectors are offline. The site still serves, but without headroom. |
| **site offline** | No connector is online. The site's apps are unreachable until one comes back. |
| **no connector** | The site has apps, but no connector has ever registered for it. |

Under each site, a row per connector shows the machine's hostname, its
operating system and architecture, its Conduit version and when it was last
seen. The connector's name comes from its hostname.

## Keep connectors up to date

The top of **Connectors** shows the current Conduit version ("conduit *version*
is current") and how many connectors run an older one. A connector that's behind
shows **update available**. Updating needs no new token: the connector keeps its
identity and comes back as the same row. The steps for each platform are in
[Upgrade the connector](/manage/conduit#upgrade-the-connector).

## What the app receives

The edge forwards each request through a connector with these headers. It
removes any copy of them the browser sent, so the app can trust them.

| Header | Value |
|---|---|
| `Trustaige-Identity-Assertion` | A signed JWT (EdDSA) saying who signed in. Always sent. |
| `Trustaige-User-Email` | The person's email address. Only with **Plain identity headers**. |
| `Trustaige-User-Groups` | The person's groups that grant this app, comma-separated. Only with **Plain identity headers**. |
| `X-Forwarded-Proto`, `X-Forwarded-Host`, `X-Forwarded-For` | The scheme and address the person used, and the address the edge saw them come from. |

The assertion's claims:

| Claim | Value |
|---|---|
| `iss` | `https://edge.trustaige.app` |
| `aud` | The app's address, such as `team-wiki.example.trustaige.app` |
| `sub` | The person's ID in your organization |
| `email`, `name` | Their email address and display name |
| `groups` | Their groups that grant this app; left out when there are none |
| `iat`, `exp` | Issued now; expires when the edge next has to check access, within a minute |

The edge publishes its public keys at `/__trustaige/jwks` on the app's own
address, such as `https://team-wiki.example.trustaige.app/__trustaige/jwks`.
Paths under `/__trustaige/` belong to the edge and never reach the app.

## If a service provider manages your organization

On a delegated session, **Mint a registration token** doesn't produce a token.
It files a request, shown on **Connectors** under **Waiting for activation**,
because a connector carries traffic into your network until someone removes it.
Once a superadmin of your organization activates the request, they see the
token and can run the connector or hand it on.

## Remove a connector or an app

**A connector.** On **Apps → Connectors**, click the bin on the connector's row,
then **Remove connector**. You'll be asked to confirm it's you. It stops carrying
traffic at once; if it was the only connector in its site, that site's apps are
unreachable until another connector is installed there. The connector on the
server stops working too. Have it uninstalled ([Remove the
connector](/manage/conduit#remove-the-connector)), since bringing it back takes a
new token anyway.

**An app.** Open the app, choose **Delete app** from its menu and confirm. The
edge stops serving its address.

## Troubleshooting

**“This page isn't available.” on Connectors or Add private app**

Private Access isn't turned on for your organization. Contact Trustaige support.

**“origin must be an http(s) URL the connector can reach”**

**Internal origin URL** must be a full address starting with `http://` or
`https://`, with a host, such as `http://wiki.internal:3000`.

**“an app already lives at … — pick a different name”**

Another of your private apps has a name that makes the same address. Choose a
different **App name**.

**“the workspace … is held by another organization — contact support to resolve the name”**

Another organization whose domain starts the same way already publishes private
apps under that name. Contact Trustaige support.

**“cannot derive a workspace address for this organization: …”**

The first part of your organization's domain can't be used in an address: it's
empty, or it's a name Trustaige keeps for itself (such as `app`, `id`, `edge` or
`www`). Contact Trustaige support.

**“sign-in gateway is not ready — register an edge key, then retry”**

The Trustaige edge isn't ready to sign people in to new apps. Nothing was
created. Try again later, and contact Trustaige support if it persists.

**“This token has expired — go back a step to mint a fresh one.”**

The token went unused for an hour. Mint a new one: from the wizard, go back a
step; otherwise, **Add connector** on **Connectors**.

**The hub stays on “Listening for the connector”**

The connector hasn't dialled in. The person running it can check its output and
the [troubleshooting on the connector page](/manage/conduit#troubleshooting).
You can leave with **Finish later**: the connector appears on **Connectors**
when it arrives.

**site offline, or “… apps are unreachable — no connector online in …”**

No connector in that site is online. Check that the connector's machine is up
and its service is running, or add a connector to the site.

**People see “This app isn't connected right now”**

They signed in and have access, but no connector for the app's site is online.
The page reloads on its own when one comes back. Check the site on
**Connectors**.

**People see “You don't have access to this application”**

They signed in, but the app is assigned to groups they aren't in, or their
membership isn't active. Add them to an assigned group.

**People see “This application isn't ready yet”**

The page says **Sign-in not configured**: the edge hasn't yet received the
sign-in settings for your organization's apps. As the page says, try again
shortly; contact Trustaige support if it persists.

**People get an empty 502 page, or “connector did not answer”**

The connector is online but couldn't reach the app at its **Internal origin
URL**, or the app didn't answer in time. From the connector's machine, check the app answers at that address; if
it serves HTTPS, the machine must trust its certificate. See [the connector's
troubleshooting](/manage/conduit#troubleshooting).
