# SecureServe

SecureServe is an early-stage, local-first secure file transfer server for macOS,
Linux, and Windows. The MVP provides:

- SFTP with encrypted transport
- Per-user private root folders
- Read-only or read/write permissions
- Bcrypt password hashing
- Ed25519 server host key
- Local administrator dashboard
- Persistent audit logging
- Path traversal protection
- HTTPS-only administrator dashboard
- Authenticator-app administrator MFA with single-use recovery codes
- SSH public-key authentication
- Authentication rate limiting
- Automatic state backups (last 10 copies)
- English end-user web portal
- Private file upload and download
- Administrator-controlled global and per-user upload limits
- Per-user storage quotas
- Allowed and blocked file-extension policies
- Automatic seven-day share URL after each upload
- Public shared downloads with expiry and audit logging
- One-time external upload-request URLs
- Guest uploads without accounts, with quota and policy enforcement

## Editions

- **SecureServe Standard — Free:** up to 5 users, global transfer policy,
  up to 5 active share links per user, 7-day audit history, and 10 backups.
- **SecureServe Pro — US$19.90/month:** up to 100 users, per-user transfer
  policies, extended audit history, and up to 100 rotating backups.

Development builds can enable Pro features by starting the server with
For local development only, Pro can be enabled with `SECURESERVE_PRO=1`.
Commercial activation uses the separate Stripe service in `billing/`. It
creates a US$19.90/month Checkout subscription and issues a short-lived,
Ed25519-signed license tied to one SecureServe installation.

To configure production license verification, copy the billing service's
base64 Ed25519 public key into `license_public_key` in `config.json`. The
application verifies `data/license.json` at startup and remains on the free
Standard plan if the signature, installation ID, product, plan, or expiry is
invalid.

## Development status

This is an MVP, not yet a production release. Before exposing it to the public
internet, enable administrator MFA, install a trusted TLS certificate, complete
an independent security review, and perform penetration testing.

## Run

```bash
go run ./cmd/secureserve
```

On the first run, SecureServe prints a randomly generated administrator password.
Open `https://127.0.0.1:8080`, sign in as `admin`, and change the password.
The first run creates a local self-signed HTTPS certificate, so the browser will
display a certificate warning until you install a trusted certificate.

After signing in, open **Administrator multi-factor authentication**, add the
displayed secret to a TOTP-compatible authenticator, and confirm the six-digit
code. Store the ten one-time recovery codes outside the SecureServe host. Once
enabled, the administrator password must be followed by an authenticator or
unused recovery code before the dashboard is accessible.

The end-user file portal is available at `https://127.0.0.1:8443`.
Users created in the administrator dashboard can sign in there with the same
credentials they use for SFTP.

Create an SFTP user in the dashboard, then connect:

```bash
sftp -P 2022 username@127.0.0.1
```

## Build

```bash
mkdir -p bin
go build -trimpath -o bin/secureserve ./cmd/secureserve
```

Create release archives for macOS, Linux, and Windows:

```bash
./scripts/build-release.sh 0.1.0
```

The script cross-compiles five platform archives under `releases/VERSION/` and
writes `SHA256SUMS.txt`. Release bundles are intentionally excluded from Git.
Unsigned archives are deterministic; Developer ID timestamping intentionally
adds the signing time to signed macOS binaries.
On macOS it automatically signs Darwin binaries when a Developer ID Application
identity is available. Set `SIGN_MACOS=1` to require signing or `SIGN_MACOS=0`
to disable it. To submit signed Darwin archives for notarization, first store a
notarytool keychain profile and set `APPLE_NOTARY_PROFILE` to its name:

```sh
APPLE_NOTARY_PROFILE=secureserve-notary ./scripts/build-release.sh 0.1.0
```

Create the native Windows x64 installer after building the release archive:

```bash
./scripts/build-windows-installer.sh \
  RELEASE_LABEL PACKAGE_VERSION releases/RELEASE_LABEL
```

The NSIS installer installs the executable and public documentation under
`Program Files\SecureServe`, registers the executable and Add/Remove Programs
entry, and preserves runtime configuration and data when uninstalled. Install
NSIS and 7-Zip with `brew install nsis p7zip` when building on macOS. The build
extracts the resulting installer and compares every payload file byte-for-byte
with the release archive. Authenticode signing still requires a Windows
code-signing certificate and remains a separate production-release step.

### macOS installer

After building and notarizing both macOS release archives, create a universal
native installer:

```bash
SIGN_INSTALLER=1 \
APPLE_NOTARY_PROFILE=secureserve-notary \
./scripts/build-macos-pkg.sh RELEASE_LABEL PACKAGE_VERSION releases/RELEASE_LABEL
```

The script verifies the notarized arm64 and amd64 binaries, combines them into a
universal executable, signs it with Developer ID Application, builds and signs a
PKG with Developer ID Installer, submits the PKG for notarization, staples the
ticket, and writes a SHA-256 file. It installs the executable at
`/usr/local/bin/secureserve` and documentation at
`/usr/local/share/doc/secureserve`. It does not create or overwrite runtime
configuration or data. The installer also repairs ownership-preserving directory
permissions left by an older SecureServe package.

To uninstall the program without deleting runtime configuration or user data:

```bash
sudo rm -f /usr/local/bin/secureserve
sudo rm -rf /usr/local/share/doc/secureserve
sudo pkgutil --forget com.lihulin.secureserve
```

Run the complete test, race, static-analysis, and vulnerability gate with:

```bash
./scripts/verify.sh
```

See [the production checklist](docs/PRODUCTION-CHECKLIST.md) before deploying.

Configuration is stored in `config.json`. Runtime state, host keys, user folders,
and audit events are stored under `data/` with restrictive permissions.

On a new installation, the generated administrator credential is written to
`data/initial-admin-password.txt` with mode `0600` instead of being printed to
service logs. The file is deleted automatically when the administrator changes
the password.
