The status board publishes component state on `GET /`. Internal notes stay on `GET /notes`, which rejects anonymous callers.

Clone [starters/flask](https://github.com/authdog/samples/tree/main/starters/flask). SDK reference: [Flask](/docs/backend/flask).

`require_auth` is the identity gate. A signed-in session is not a permission grant. Apply [authorization](/docs/concepts/authorization) after the gate.

## What you need

| Requirement | Detail |
| --- | --- |
| Public key | `pk_...` from the [console](https://console.authdog.com) |
| Environment | Copy `.env.example` to `.env` and export `PK_AUTHDOG` |
| Secret key | Never put `sk_...` in the service |
| Package | Flask extra is source in [authdog/web-sdk](https://github.com/authdog/web-sdk) `packages/python`. It is not the `authdog` package on PyPI. Python 3.10+ |
| Request | Hosted sign-in stays in a browser. Call `/notes` with the `authdog-session` cookie or `Authorization: Bearer` |

## Run

```bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
export PK_AUTHDOG=pk_...
flask --app main run --port 3000
```

`GET /` returns API (operational) and Account portal (degraded) with no session. `GET /notes` with a valid session returns `note_7` (Account portal latency). Without a session it is rejected.

## Public status and private notes

```python
# main.py
import os

from authdog.flask import Authdog
from flask import Flask, jsonify

authdog = Authdog(public_key=os.environ["PK_AUTHDOG"])
app = Flask(__name__)

@app.get("/")
def index():
    return jsonify(
        {
            "components": [
                {"name": "API", "state": "operational"},
                {"name": "Account portal", "state": "degraded"},
            ]
        }
    )

@app.get("/notes")
@authdog.require_auth
def notes():
    return jsonify(
        {
            "caller": authdog.session().user,
            "notes": [
                {
                    "id": "note_7",
                    "component": "Account portal",
                    "text": "Identity host latency above 800ms.",
                }
            ],
        }
    )
```

The decorator works on blueprint views the same way. `fetch_user=False` leaves `is_authenticated` false, so the decorator rejects.
