# Security and privacy

Source: https://laraport.app/docs/security/

> What laraport runs on your servers, where passwords and secrets go, what it stores on your computer, and what the update check and this website collect.

## On your servers

- laraport installs nothing on servers or in containers. It runs `docker` commands over SSH, the ones you would type yourself.
- Every command run in a container is passed to `sh -c` as one quoted word, and every value in it (paths, database names) is quoted on its own, so nothing is expanded by the server's shell.
- Long-running commands (`tail -f`, a query, a dump) are stopped on the server when you leave the screen.

## Secrets

- Database passwords, Redis passwords, Tinker code and file contents are passed over stdin, never as command-line arguments where other users of the server could read them with `ps`.
- Credentials found in containers are used for the command that needs them and never written to laraport's config.
- Secret values on the Environment screen are masked until you press `v`.

## Changes

- Anything that changes or deletes data asks first and shows the exact command or SQL.
- In production apps (`APP_ENV=production`), Tinker asks before the first run and table editing has to be switched on. Deploy commands and restores say when the app is production.
- Restoring dumps is off until you switch on **Allow restoring dumps**, and each restore runs only after you type the database's name.
- Edited files are saved only if they did not change since you opened them, and the previous version is kept in the container.
- Every change is recorded in the [journal](https://laraport.app/docs/journal/) on your computer, before it runs.

## Read-only servers

Mark a server **Read-only** (`read_only: true`) and laraport refuses everything that would change it, in one place, before a screen opens or a command runs:

- commands other than known reads (`route:list`, `composer show`…), container, Swarm and Compose actions, deploy commands and prunes;
- editing and uploading files, editing table data, SQL other than a single `SELECT`;
- Tinker, shells, deleting Redis keys, restores and tunnels.

Logs, tables, `SELECT` queries, viewing files, inspect, events and downloads work as usual. Read-only guards laraport's own actions; for a guarantee at the database, connect with a read-only database user. The full lists are in [Read-only servers](https://laraport.app/docs/read-only/).

## Tunnels

A [tunnel](https://laraport.app/docs/tunnels/) to the app's database or Redis listens on `127.0.0.1` only, so no other machine can use it. Nothing is installed or opened on the server: each connection is relayed by PHP in the app's container. The tunnel closes when you leave its screen.

## On your computer

- No telemetry. laraport talks to your servers, and once a day to GitHub to check for a newer release (see below).
- `config.yaml` is written with mode `0600`.
- The history of SQL queries, Tinker code and Artisan, Composer and npm commands is stored unencrypted in `~/.config/laraport/history.json`, mode `0600`. Turn it off with `no_sql_history`.
- The journal (`journal.jsonl`) and the list of recent containers (`recent.json`) are kept in `~/.config/laraport/`, mode `0600`. Passwords never reach the journal.
- Dumps and downloads are saved with mode `0600`.
- SSH host keys are verified against `~/.ssh/known_hosts`. See [Host keys](https://laraport.app/docs/servers/#host-keys).

## The update check

Once a day laraport asks the GitHub API for its latest release, to say on the home screen when a newer one is out.

- It is one GET request with `laraport/<version>` as the user agent. Nothing about you or your servers is sent.
- The answer is kept for a day in `~/.config/laraport/update.json`.
- Development builds never ask, and a failure stays silent.
- **Check for new versions** in Settings (`no_update_check: true`), or `LARAPORT_NO_UPDATE_CHECK=1`, turns it off.

## This website

laraport itself sends nothing. The website laraport.app is another matter: it counts its visits, to know how many people read it and what they read.

- Its own counter sets no cookies and keeps the numbers on the site's server. Addresses are not stored: a visitor is a hash of the address and the browser with a random salt that is deleted the next day, so the same person can no longer be recognised after that.
- Google Analytics sends the visit to Google, and sets cookies to tell visits apart. In the EEA, the UK and Switzerland it sets them only if you agree: until then, or if you reject them, it receives cookieless pings only. Elsewhere the cookies are on unless you say no.
- Browsers that send Do Not Track or Global Privacy Control are counted by neither, and see no banner.

*Cookie settings* at the bottom of every page changes your choice.

| Name | Type | Purpose | Lifetime |
| --- | --- | --- | --- |
| `_ga`, `_ga_*` | Cookie | Google Analytics: tells visits apart for aggregate statistics | Up to 2 years |
| `laraport-consent` | Local storage | Remembers your choice about these cookies | Until cleared |
| `starlight-theme` | Local storage | Remembers the light or dark theme you chose | Until cleared |
