Documentation cleanup for public release (#38)

* docs: cleanup for public release (fix stale/wrong API docs, LICENSE, versions)

Documentation cleanup ahead of the public release announcement. Fixes a set
of confirmed issues from a prior audit:

- LICENSE: fill in MIT template placeholders (theta42, 2026).
- README.md: fix broken API docs link (api.md -> API.md), correct required
  Node.js version (13.x -> 20.x), add the missing app_sso_invite group to
  the LDAP groups table, scrub hardcoded dc=theta42,dc=com to the generic
  dc=example,dc=com used elsewhere, add a "Recommended: Docker or
  install.sh" section pointing to DEPLOYMENT.md/docs before the manual
  OpenLDAP walkthrough, and drop an emoji from a warning callout.
- nodejs/api.md: deleted — it was a stale/legacy doc with wrong routes,
  wrong request bodies, and endpoints that are dead/commented-out code.
  The root API.md is the accurate, current reference; README now links
  there directly.
- API.md: add the missing app_sso_invite permission group, fix the
  documented invite response to match the real {token, link, mail_sent}
  payload, document the previously-undocumented GET/PUT/DELETE
  /api/user/invite endpoints, add the real allowed_groups field to the
  OAuth client management examples, and document POST /api/oauth/authorize
  (the endpoint that actually issues the code after consent).
- nodejs/routes/auth.js + API.md: fix "emaill address" typo in the
  password-reset response message (source and docs kept in sync).
- DEPLOYMENT.md: fix the top-level summary to mention Redis, matching
  docs/deployment.md and the entrypoint behavior it already documents.

Flagged, not changed: tos.md reads like a personal home-lab acceptable-use
policy (Emby/Gitea/Proxmox/Discord/Signal, first-person "the admin") rather
than generic OSS docs. Left in place pending a manual decision to
genericize, relocate, or remove it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs: genericize tos.md template, track runtime-editable terms in #39

Removes operator-specific references (Emby, Gitea, Proxmox, Discord,
Signal, first-person "the admin") so the shipped tos.md reads as a
neutral starting template rather than one operator's internal policy.
Actual runtime editability (admin/legal editing terms without a code
change) is tracked in issue #39, not implemented here.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 23:21:27 -04:00
committed by GitHub
parent 11fb2c0a54
commit 158109de59
7 changed files with 180 additions and 92 deletions
+125 -5
View File
@@ -38,6 +38,7 @@ auth-token: <token>
|-------|--------| |-------|--------|
| `app_sso_admin` | Full user/group/notification management | | `app_sso_admin` | Full user/group/notification management |
| `app_sso_oauth_admin` | Register and manage OAuth clients | | `app_sso_oauth_admin` | Register and manage OAuth clients |
| `app_sso_invite` | Invitation management |
| Group owner | Manage membership of that specific group | | Group owner | Manage membership of that specific group |
Self-service: users can always read and modify their own account without admin membership. Self-service: users can always read and modify their own account without admin membership.
@@ -116,7 +117,7 @@ Returns available username suggestions based on name and optional date of birth.
**Response:** **Response:**
```json ```json
{ "message": "If the emaill address is in our system, you will receive a message." } { "message": "If the email address is in our system, you will receive a message." }
``` ```
The same response is returned whether or not the email exists. Reset tokens expire after 24 hours. The same response is returned whether or not the email exists. Reset tokens expire after 24 hours.
@@ -506,11 +507,90 @@ When an admin changes another user's password, `password_must_change` is set on
### Generate Invite Token ### Generate Invite Token
**`POST /api/user/invite`** — Any authenticated user Create an invite token, optionally emailing it to the invitee and pre-assigning
LDAP groups the new account should be added to on signup.
**`POST /api/user/invite`** — `app_sso_admin` or `app_sso_invite` required
**Request:**
```json
{ "mail": "invitee@example.com", "groups": ["group_name"] }
```
`mail` and `groups` are both optional. If `mail` is provided, a verification
email is sent to that address.
**Response:** **Response:**
```json ```json
{ "token": "invite_token_string" } {
"token": "invite_token_string",
"link": "https://your-domain.com/login/invite/invite_token_string",
"mail_sent": true
}
```
---
### List Invite Tokens
**`GET /api/user/invite`** — `app_sso_admin` or `app_sso_invite` required
Admins (`app_sso_admin`) see all invite tokens; non-admin `app_sso_invite`
members see only invites they created.
**Response:**
```json
{
"results": [
{
"token": "invite_token_string",
"created_by": "username",
"created_on": 1234567890000,
"is_valid": true,
"mail": "invitee@example.com",
"groups": "[\"group_name\"]"
}
]
}
```
---
### Update Invite Token
Update the groups an invite will assign, or change/clear the invitee's email
(re-sends verification if a new email is set).
**`PUT /api/user/invite/:token`** — `app_sso_admin`, or the `app_sso_invite`
member who created the invite
**URL Parameters:** `token` — invite token
**Request:** Any subset of:
```json
{ "groups": ["group_name"], "mail": "newinvitee@example.com" }
```
Set `mail` to `null`/empty to clear it. Fails with `400` if the token is no
longer valid.
**Response:**
```json
{ "results": { "token": "invite_token_string", "is_valid": true, "...": "..." } }
```
---
### Revoke Invite Token
**`DELETE /api/user/invite/:token`** — `app_sso_admin`, or the `app_sso_invite`
member who created the invite
**URL Parameters:** `token` — invite token
**Response:**
```json
{ "results": true }
``` ```
--- ---
@@ -831,7 +911,44 @@ Returns the OIDC discovery document with endpoint URLs, supported scopes, and si
- `code_challenge` — PKCE challenge (SHA-256 of code_verifier, base64url-encoded) - `code_challenge` — PKCE challenge (SHA-256 of code_verifier, base64url-encoded)
- `code_challenge_method` — Must be `S256` - `code_challenge_method` — Must be `S256`
Renders the consent screen. On approval, redirects to `redirect_uri?code=<code>&state=<state>`. Renders the consent screen.
---
### Authorize (Issue Code)
Issues the authorization code after the user approves the consent form shown
by the Authorization Endpoint above. This is called by the consent page itself
(an authenticated request, via `auth-token`), not by the OAuth client
directly.
**`POST /api/oauth/authorize`** — Auth required (`auth-token` header)
**Request:**
```json
{
"response_type": "code",
"client_id": "uuid",
"redirect_uri": "https://ha.example.com/auth/external/callback",
"scope": "openid profile email",
"state": "opaque-state-value",
"code_challenge": "pkce-challenge",
"code_challenge_method": "S256"
}
```
Only scopes the client is actually registered for are granted, even if more
are requested. If the client has `allowed_groups` set, the authenticated user
must be a member of at least one of those groups or the request is rejected
with `403`.
**Response:**
```json
{ "redirect_url": "https://ha.example.com/auth/external/callback?code=<code>&state=<state>" }
```
The caller (the consent page) redirects the browser to `redirect_url`, which
completes the flow described in the Authorization Endpoint section above.
--- ---
@@ -916,6 +1033,7 @@ All endpoints require authentication and `app_sso_oauth_admin` membership.
"description": "Home automation", "description": "Home automation",
"redirect_uris": ["https://ha.example.com/auth/external/callback"], "redirect_uris": ["https://ha.example.com/auth/external/callback"],
"scopes": ["openid", "profile", "email"], "scopes": ["openid", "profile", "email"],
"allowed_groups": [],
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 }, "token_lifetime": { "access_token": 3600, "refresh_token": 2592000 },
"created_by": "wmantly", "created_by": "wmantly",
"created_on": 1234567890000 "created_on": 1234567890000
@@ -937,11 +1055,13 @@ All endpoints require authentication and `app_sso_oauth_admin` membership.
"description": "Home automation dashboard", "description": "Home automation dashboard",
"redirect_uris": ["https://ha.example.com/auth/external/callback"], "redirect_uris": ["https://ha.example.com/auth/external/callback"],
"scopes": ["openid", "profile", "email"], "scopes": ["openid", "profile", "email"],
"allowed_groups": [],
"token_lifetime": { "access_token": 3600, "refresh_token": 2592000 } "token_lifetime": { "access_token": 3600, "refresh_token": 2592000 }
} }
``` ```
`redirect_uris` may also be a newline-separated string. `scopes` may also be a space-separated string. `redirect_uris` may also be a newline-separated string. `scopes` may also be a space-separated string.
`allowed_groups` restricts the client to members of the listed SSO groups (empty/omitted = any valid user).
**Response:** **Response:**
```json ```json
@@ -968,7 +1088,7 @@ The `client_secret` is shown **only once**. Store it immediately.
**`PUT /api/oauth/client/:client_id`** **`PUT /api/oauth/client/:client_id`**
**Request:** Any subset of `name`, `description`, `redirect_uris`, `scopes`, `token_lifetime`, `is_valid`. **Request:** Any subset of `name`, `description`, `redirect_uris`, `scopes`, `allowed_groups`, `token_lifetime`, `is_valid`.
**Response:** `{ "results": { <updated client> }, "message": "..." }` **Response:** `{ "results": { <updated client> }, "message": "..." }`
+3 -3
View File
@@ -2,8 +2,8 @@
Two supported deployment methods: Two supported deployment methods:
1. **Docker** — a single all-in-one image bundling the app + OpenLDAP (`docker compose up`). 1. **Docker** — a single all-in-one image bundling the app + OpenLDAP + Redis (`docker compose up`).
2. **Bare metal**`install.sh` on Debian/Ubuntu (installs Node.js, OpenLDAP, the app, and a systemd unit). 2. **Bare metal**`install.sh` on Debian/Ubuntu (installs Node.js, OpenLDAP, Redis, the app, and a systemd unit).
## How configuration works ## How configuration works
@@ -39,7 +39,7 @@ as raw strings otherwise. Examples:
## Method 1: Docker (all-in-one) ## Method 1: Docker (all-in-one)
The image (`Dockerfile.openldap`) bundles OpenLDAP and the app in one container. The image (`Dockerfile.openldap`) bundles OpenLDAP, Redis, and the app in one container.
The app connects to the bundled slapd over `localhost:389` automatically; you only The app connects to the bundled slapd over `localhost:389` automatically; you only
need to set a few secrets. need to set a few secrets.
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) <year> <copyright holders> Copyright (c) 2026 theta42
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+30 -10
View File
@@ -1,12 +1,31 @@
# SSO manager # SSO manager
## API docs ## API docs
[API docs](api.md) [API docs](API.md)
## Server set up ## Server set up
### Recommended: Docker or install.sh
The supported, tested deployment paths are **Docker** (an all-in-one image
bundling the app + OpenLDAP + Redis) and the **`install.sh`** bare-metal
installer for Debian/Ubuntu. Most users should start there:
- [Deployment Guide](DEPLOYMENT.md) — Docker + bare metal, configuration
layers, backups, troubleshooting.
- [docs/index.md](docs/index.md) — documentation home (also published as a
GitHub Pages site), with links to configuration, LDAP, and OAuth/OIDC docs.
### Manual / advanced: raw OpenLDAP setup
The rest of this section walks through configuring OpenLDAP by hand. This is
the **manual/advanced path** — useful if you're pointing the app at an
existing LDAP server, or want to understand exactly what `install.sh` and the
Docker entrypoint automate for you. Most deployments should use Docker or
`install.sh` above instead.
The server requires: The server requires:
* NodeJS 13.x * NodeJS 20.x
* LDAP server * LDAP server
> Setting up the whole stack (Docker) or want the secrets-file layout? See > Setting up the whole stack (Docker) or want the secrets-file layout? See
@@ -63,11 +82,11 @@ EOF
**2. Add the overlay to your user database:** **2. Add the overlay to your user database:**
> ⚠️ The database index below (`{1}mdb`) is **not** the same on every install. Confirm yours first — the overlay must go on the database whose `olcSuffix` is your base DN, or account locking silently won't apply to your users: > Warning: The database index below (`{1}mdb`) is **not** the same on every install. Confirm yours first — the overlay must go on the database whose `olcSuffix` is your base DN, or account locking silently won't apply to your users:
> >
> ```bash > ```bash
> ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config \ > ldapsearch -Q -Y EXTERNAL -H ldapi:/// -b cn=config \
> '(&(objectClass=olcDatabaseConfig)(olcSuffix=dc=theta42,dc=com))' dn > '(&(objectClass=olcDatabaseConfig)(olcSuffix=dc=example,dc=com))' dn
> ``` > ```
```bash ```bash
@@ -76,7 +95,7 @@ dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig objectClass: olcPPolicyConfig
olcOverlay: ppolicy olcOverlay: ppolicy
olcPPolicyDefault: cn=ppolicy,ou=policies,dc=theta42,dc=com olcPPolicyDefault: cn=ppolicy,ou=policies,dc=example,dc=com
olcPPolicyUseLockout: TRUE olcPPolicyUseLockout: TRUE
olcPPolicyHashCleartext: FALSE olcPPolicyHashCleartext: FALSE
EOF EOF
@@ -85,12 +104,12 @@ EOF
**3. Create the policies container and default policy:** **3. Create the policies container and default policy:**
```bash ```bash
ldapadd -x -D "cn=admin,dc=theta42,dc=com" -W << 'EOF' ldapadd -x -D "cn=admin,dc=example,dc=com" -W << 'EOF'
dn: ou=policies,dc=theta42,dc=com dn: ou=policies,dc=example,dc=com
objectClass: organizationalUnit objectClass: organizationalUnit
ou: policies ou: policies
dn: cn=ppolicy,ou=policies,dc=theta42,dc=com dn: cn=ppolicy,ou=policies,dc=example,dc=com
objectClass: top objectClass: top
objectClass: organizationalRole objectClass: organizationalRole
objectClass: pwdPolicy objectClass: pwdPolicy
@@ -105,8 +124,8 @@ EOF
Verify by locking a test account and confirming bind fails: Verify by locking a test account and confirming bind fails:
```bash ```bash
ldapmodify -x -D "cn=admin,dc=theta42,dc=com" -W << 'EOF' ldapmodify -x -D "cn=admin,dc=example,dc=com" -W << 'EOF'
dn: cn=testuser,ou=people,dc=theta42,dc=com dn: cn=testuser,ou=people,dc=example,dc=com
changetype: modify changetype: modify
replace: pwdAccountLockedTime replace: pwdAccountLockedTime
pwdAccountLockedTime: 000001010000Z pwdAccountLockedTime: 000001010000Z
@@ -153,6 +172,7 @@ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=theta42,cn=schema,cn=config" olcAttri
|-------|---------| |-------|---------|
| `app_sso_admin` | Full admin access: manage users, groups, OAuth clients | | `app_sso_admin` | Full admin access: manage users, groups, OAuth clients |
| `app_sso_oauth_admin` | Manage OAuth clients only | | `app_sso_oauth_admin` | Manage OAuth clients only |
| `app_sso_invite` | Invitation management |
## Logs (Docker) ## Logs (Docker)
-60
View File
@@ -1,60 +0,0 @@
## create invite token
**post** `/users/invite`
```bash
curl -H "Content-Type: application/json" -H "auth-token: 0b06eb2e-4ca4-4881-9a0f-b8df55431cd1" -X POST https://proxy-host.com/users/invite
```
* 200 {"token":"5caf94d2-2c91-4010-8df7-968d10802b9d"}
## sing up
**post** `/auth/invite/<INVITE TOKEN>`
```bash
curl -H "Content-Type: application/json" -X POST -d "{\"username\": \"test9\", \"password\": \"palm7\"}" https://proxy-host.com/auth/invite/b33d8819-ec64-4cf4-a6ec-77562d738fa4
```
* 200 {"user":"test9","token":"af662d8b-3d44-4110-8ad9-047dc752d97f"}
* 400 {"message":"Missing fields"}
* 401 {"message":"Token not valid"}
* 409 {"message":"username taken"}
## login
**post** `/auth/login`
```bash
curl -H "Content-Type: application/json" -X POST -d '{"username": "test8", "password": "mypassword"}' https://proxy-host.com/auth/login
```
* 200 {"login":true,"token":"027d3964-7d81-4462-a6f9-2c1f9b40b4be"}
* 401 {"login":false}
## verify SSH key
**post** `/auth/verifykey`
```bash
curl -H "Content-Type: application/json" -X POST -d "{\"key\":\"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDM9vboz5YGgESsrR2e4JOeP2qtmQo2S8BjI+Y/VxPQ6WbNFzAkXxDniHcnPCrhkeX36SKINvMjWnt4XOK2S+X+1tCoXJzqtcKKyK0gx8ijBxcWVPxsMWjMYTGSVSKiKnt6CyQzrbVGJMh3iAQ8Yv1JwH+6SAtMgT8it7iLyntNFJCesh4I/znEG58A5VBbdUle1Ztz9afjj1CZns17jk7KPm9ig5DmuvdvnMEfhFjfKv1Rp6S5nxacMoTP4tJNSEUh55IicoWk94ii5GwUVLYgyMmzdlA32TqVLFpU2yAvdA9WSnBaI/ZyktlfI7YAmK2wFBsagr9Pq1TcUAY6rZ/GTMjDxExgdYn/FxlufcuqeNJsJXs2A+0xDS/9mv/yGQzNZrL8DrVhY2OKKLoH4Q7enDbhSgEFmJUJMqPxuPEgLEvKfzcURSvIwRj1iCEw6S4dhdaLJl2RRBb1ZWBQbE5ogIbvAl7GFJUAhj3pqYJnd30VENv1MkK+IoCS7EEP0caqL9RNAId0Plud7q2XElHqzkYUE+z+Q/LvGgclXK1ZmZejNaMnV53wfhAevfwVyNGK9i5gbwc1P2lplIa5laXCcVWezqELEkTpdjp4AeKmMuCr8rY8EnLKIcKWEOsX5UumztCow6e1E55v3VeHvRZLpw4DZP7EE0Q8B/jPFWqbCw== wmantly@gmail.com\"}" https://proxy-host.com/auth/verifykey
```
* 200 {"info":"4096 SHA256:dfdCYzt0atMBXVZTJzUxsu99IjXXFXpocSox5q+jOs8 wmantly@gmail.com (RSA)\n"}
* 400 {"message":"Key is not a public key file!"}
## add ssh key to current user
**post** `/users/key`
```bash
curl -H "Content-Type: application/json" -H "auth-token: 8eff4f16-086d-40fd-acbd-7634b9a36117" -X POST -d "{\"key\": \"ssh-rsa AAAAB3NzaC1yc2EAAjWnt4XOK2S+X+1tCoXJzqtcKKyK0gx8ijBxcWVPxsMWjMYTGSVSKiKnt6CyQzrbVGJMh3iAQ8Yv1JwH+6SAtMgT8it7iLyntNFJCesh4I/znEG58A5VBbdUle1Ztz9afjj1CZns17jk7KPm9ig5DmuvdvnMEfhFjfKv1Rp6S5nxacMoTP4tJNSEUh55IicoWk94ii5GwUVLYgyMmzdlA32TqVLFpU2yAvdA9WSnBaI/ZyktlfI7YAmK2wFBsagr9Pq1TcUAY6rZ/GTMjDxExgdYn/FxlufcuqeNJsJXs2A+0xDS/9mv/yGQzNZrL8DrVhY2OKKLoH4Q7enDbhSgEFmJUJMqPxuPEgLEvKfzcURSvIwRj1iCEw6S4dhdaLJl2RRBb1ZWBQbE5ogIbvAl7GFJUAhj3pqYJnd30VENv1MkK+IoCS7EEP0caqL9RNAId0Plud7q2XElHqzkYUE+z+Q/LvGgclXK1ZmZejNaMnV53wfhAevfwVyNGK9i5gbwc1P2lplIa5laXCcVWezqELEkTpdjp4AeKmMuCr8rY8EnLKIcKWEOsX5UumztCow6e1E55v3VeHvRZLpw4DZP7EE0Q8B/jPFWqbCw== wmantly@gmail.co\"}" https://proxy-host.com/users/key
```
* 200 {"message":true}
* 400 {"message":"Bad SSH key"}
+1 -1
View File
@@ -66,7 +66,7 @@ router.post('/resetpassword', rateLimit.passwordReset, async function(req, res,
console.info('resetpassword for', req.body.mail, 'sent') console.info('resetpassword for', req.body.mail, 'sent')
return res.json({ return res.json({
message: 'If the emaill address is in our system, you will receive a message.' message: 'If the email address is in our system, you will receive a message.'
}); });
}catch(error){ }catch(error){
next(error); next(error);
+20 -12
View File
@@ -2,19 +2,27 @@
*Last updated: June 2026* *Last updated: June 2026*
Welcome to Theta42. By creating an account and using any services on this system, you agree to the following terms. Please read them carefully — they're short and written in plain English. > **This is a template.** SSO Manager ships this file as a starting point for
> operators to adapt to their own deployment, organization name, and
> jurisdiction. Replace the placeholder text below (or the whole document)
> with terms reviewed by your own admin/legal before relying on it. See
> [issue #39](https://github.com/theta42/sso-manager-node/issues/39) for the
> planned admin UI that will let operators edit this document without a code
> change.
Welcome. By creating an account and using any services on this system, you agree to the following terms. Please read them carefully — they're short and written in plain English.
--- ---
## 1. Who This Applies To ## 1. Who This Applies To
These terms apply to anyone with an account on Theta42 systems, including but not limited to: SSH access, Emby, Gitea, self-managed containers or VMs, Proxmox, and any other services accessible with your credentials. These terms apply to anyone with an account on this system, including but not limited to: SSH access, self-managed containers or VMs, and any other services accessible with your credentials.
--- ---
## 2. Acceptable Use ## 2. Acceptable Use
- **Be respectful.** Treat other users and the admin with respect. Harassment, abuse, or intentionally disrupting other users' work is not tolerated. - **Be respectful.** Treat other users and administrators with respect. Harassment, abuse, or intentionally disrupting other users' work is not tolerated.
- **Do no harm.** Do not attempt to access, modify, damage, or disrupt any system, service, or data you are not explicitly authorized to use — including systems outside this network. - **Do no harm.** Do not attempt to access, modify, damage, or disrupt any system, service, or data you are not explicitly authorized to use — including systems outside this network.
- **No malicious activity.** Do not use your account to run port scans, exploits, denial-of-service attacks, spam campaigns, or any other activity intended to harm others. - **No malicious activity.** Do not use your account to run port scans, exploits, denial-of-service attacks, spam campaigns, or any other activity intended to harm others.
- **No resource abuse.** Do not use shared infrastructure for cryptocurrency mining, bulk email, or other activities that consume excessive CPU, memory, disk, or bandwidth without prior approval. - **No resource abuse.** Do not use shared infrastructure for cryptocurrency mining, bulk email, or other activities that consume excessive CPU, memory, disk, or bandwidth without prior approval.
@@ -23,36 +31,36 @@ These terms apply to anyone with an account on Theta42 systems, including but no
## 3. Legal Compliance ## 3. Legal Compliance
- You agree to comply with all applicable **United States federal law** and the laws of **your current jurisdiction**. - You agree to comply with all applicable laws in your jurisdiction and the jurisdiction where this service is operated.
- Do not store, transmit, access, or distribute any content that is illegal under US law or the laws where you are located. - Do not store, transmit, access, or distribute any content that is illegal under applicable law.
- This includes but is not limited to: pirated software, copyrighted content you do not have rights to, and any material that is illegal in your jurisdiction. - This includes but is not limited to: pirated software, copyrighted content you do not have rights to, and any material that is illegal in your jurisdiction.
--- ---
## 4. Credential Security ## 4. Credential Security
- Do not share your password, SSH keys, or any other credentials with anyone — including the admin (who will never ask for your password). - Do not share your password, SSH keys, or any other credentials with anyone — including administrators (who will never ask for your password).
- You are responsible for all activity that occurs under your account. - You are responsible for all activity that occurs under your account.
- If you suspect your account has been compromised, notify the admin immediately and change your password. - If you suspect your account has been compromised, notify an administrator immediately and change your password.
--- ---
## 5. Self-Managed Resources ## 5. Self-Managed Resources
Users with access to containers, virtual machines, or Proxmox agree to additional responsibilities: Users with access to containers or virtual machines agree to additional responsibilities:
- You are **fully responsible** for everything you run inside your allocated resources. - You are **fully responsible** for everything you run inside your allocated resources.
- Keep your systems patched and reasonably secured. A compromised VM on the network is everyone's problem. - Keep your systems patched and reasonably secured. A compromised VM on the network is everyone's problem.
- Do not use your allocation to attack, scan, or probe other systems — on this network or anywhere else. - Do not use your allocation to attack, scan, or probe other systems — on this network or anywhere else.
- Resource abuse (running workloads that harm shared infrastructure or network performance) may result in immediate suspension of your allocation. - Resource abuse (running workloads that harm shared infrastructure or network performance) may result in immediate suspension of your allocation.
- Do not expose services to the internet without coordinating with the admin. - Do not expose services to the internet without coordinating with an administrator.
--- ---
## 6. Privacy ## 6. Privacy
- Your personal data (name, email address, phone number) is stored solely to operate this service. It will not be sold, rented, or shared with third parties. - Your personal data (name, email address, phone number) is stored solely to operate this service. It will not be sold, rented, or shared with third parties.
- **The admin reserves the right to inspect** activity logs, files, running processes, and system usage on shared infrastructure at any time — for security purposes, incident investigation, or to verify compliance with these terms. - **Administrators reserve the right to inspect** activity logs, files, running processes, and system usage on shared infrastructure at any time — for security purposes, incident investigation, or to verify compliance with these terms.
- **You have no expectation of privacy** on systems, storage, or network traffic hosted on this infrastructure. - **You have no expectation of privacy** on systems, storage, or network traffic hosted on this infrastructure.
--- ---
@@ -60,7 +68,7 @@ Users with access to containers, virtual machines, or Proxmox agree to additiona
## 7. Account Termination ## 7. Account Termination
- Violation of any of these terms may result in **immediate account suspension or deletion without prior notice**. - Violation of any of these terms may result in **immediate account suspension or deletion without prior notice**.
- The admin reserves sole discretion to terminate access for any reason. - Administrators reserve sole discretion to terminate access for any reason.
--- ---
@@ -72,4 +80,4 @@ This agreement may be updated at any time. The current version is always availab
## Questions? ## Questions?
Reach the admin through the SSO manager or through the associated communication channels (Discord, Signal, etc.). Reach an administrator through the SSO manager or your organization's usual support channel.