> ## Documentation Index
> Fetch the complete documentation index at: https://getfloo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Internal Tools

> Ship an app your team signs into with their work email — no devops project, no access-control to set up, no provisioning queue.

The most valuable software your team runs is the software you build for yourselves — the lookup tool, the admin panel, the operations dashboard, the approval flow. floo is built to make that the easy path, not the hard one.

## The problem with "just ship an internal tool"

Normally, shipping a tool for your team looks like this:

1. Build the app.
2. Figure out where to host it.
3. Put auth in front of it.
4. Figure out who gets access, and how they're provisioned.
5. Keep it running.

Steps 2–5 are the actual project. floo collapses them into one config file.

## The floo flow

### 1. Build the app

Any web service (Node, Python, Go, Rust, static) with a Dockerfile.

### 2. Turn on managed auth

In `floo.app.toml`:

```toml theme={null}
[app]
name = "team-directory"
access_mode = "accounts"

[services.web]
type = "web"
port = 3000
ingress = "public"
```

That's it — `access_mode = "accounts"` is the entire auth config. floo's gateway sits in front of your app, redirects unauthenticated visitors to a hosted sign-in page, manages the session cookie, and tells you who the user is on every request.

### 3. Restrict sign-in to your team

In the dashboard, under the app's Users tab, add your company email domain to the allowlist (e.g., `acme.com`). Only people with an `@acme.com` email can sign in.

### 4. Deploy

```bash theme={null}
git push origin main
floo deploys watch --app team-directory
```

Once it's live, share the URL. Teammates click sign-in, authenticate with their work email, and they're in. No provisioning tickets, no new password, no access-control project.

## What your app code does

When a signed-in user hits your app, floo's gateway injects identity headers into the request. Read them like any other header:

```js theme={null}
app.use((req, _res, next) => {
  req.user = {
    id:    req.get('x-floo-user-id'),
    email: req.get('x-floo-user-email'),
    name:  req.get('x-floo-user-name'),
  };
  next();
});
```

That's the entire integration. No JWT verification, no client library, no session storage. The gateway has already validated the user before the request reached your app.

See [Add User Auth to Your App](/docs/guides/app-auth) for the full reference.

## Promoting to production

After the app is good in dev, promote it:

```bash theme={null}
floo releases promote --app team-directory --tag v1
```

Your team now uses the production URL at `team-directory.on.getfloo.com`. The dev URL stays live for you to iterate without affecting the version your team relies on.

## Who is using it

The app's Users tab shows everyone who has signed in: email, first seen, last active, and how often. The org-level Users page rolls that up across every internal tool you've shipped.

This is a side effect of using managed auth — you get usage data without building analytics.

<CardGroup cols={2}>
  <Card title="Managed auth reference" href="/docs/guides/app-auth">
    Identity headers, access policies, and access modes in detail.
  </Card>

  <Card title="Custom domains" href="/docs/guides/custom-domains">
    Put the internal tool on `tools.yourcompany.com` instead of the default floo URL.
  </Card>
</CardGroup>
