New "Sync from phpIPAM" action on IP Addresses, alongside the existing
"Sync from Tailscale" / "Sync from Proxmox" ones and built the same way:
a new integration type (config in-app, URL + API app ID + app token,
credentials encrypted at rest) that this page pulls from on demand.
Deliberately import-only, not a full integration -- no dedicated page,
dashboard widget, or nav entry, since that's all this was asked for.
Auth is phpIPAM's static "App token" method: create an API app under
Administration -> API with its security set to "SSL with App token", and
its one-time code goes straight in as the `token` header (also sent as
`phpipam-token`, in case a given version expects that name instead) --
no login call, no token to renew. The user/password "User token" method
isn't implemented.
Addresses are read the standard way: GET /subnets/, then GET
/subnets/{id}/addresses/ for each, rather than assuming a single
"all addresses" endpoint exists on every version. phpIPAM wraps every
response as {code, success, data} -- including an empty result: a subnet
with nothing in it answers success:false, message:"No addresses found"
rather than success:true, data:[]. That's read as "nothing here", not a
failure; anything else with success:false throws with phpIPAM's own
message. One subnet failing outright (e.g. the app lacks permission on
it) is skipped with a note rather than aborting the whole sync. Every
address field is read defensively -- optional, independently
type-checked -- so a field phpIPAM renames or drops in some version
leaves that value blank instead of breaking the import.
Imported entries: label from hostname or description, "phpIPAM" as
vendor, the subnet's own description (or its CIDR, if it has none) as
location, and description/note/MAC folded into notes. Existing sync
plumbing (upsertSyncedEntry) gained a location parameter so this and any
future sync can set it; the two existing syncs pass null, unchanged.
Endpoints, the token header, and the address/subnet field names are
cross-checked against phpIPAM's own published API documentation. Not
verified against a live instance -- there wasn't one available while
building this, so if a real sync comes back empty or with the wrong
fields, that's the next thing to check.
Verified with 23 backend checks against a fake phpIPAM server matching
that documented shape (the empty-subnet quirk, a subnet that fails
outright, malformed/missing fields, a non-JSON response) and the real
route (added/updated/skipped counts, a manually-entered IP never
overwritten, roles, no-enabled-integration, upstream failure surfaced
per-integration rather than as a 500, audit entries) plus a browser check
of the real IP Addresses page against the real routers: the sync button,
its result message, re-syncing (updates rather than duplicates), the
manual entry staying untouched, and the viewer view.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
145 lines
11 KiB
Markdown
145 lines
11 KiB
Markdown
# Integration & DNS provider access requirements
|
|
|
|
What credential to create in each target system, and the minimum
|
|
access it needs, when adding an integration or DNS provider in
|
|
Homelab Manager (Integrations → Add integration, or DNS → Add
|
|
provider). All credentials are entered in-app and encrypted at rest —
|
|
nothing is read from environment variables.
|
|
|
|
Every adapter listed here performs write actions (starting/stopping
|
|
things, editing DNS records, etc.), not just reads — a read-only
|
|
credential will fail as soon as you use one of those actions, even if
|
|
the dashboard views themselves load fine.
|
|
|
|
## Integrations
|
|
|
|
### Tailscale
|
|
|
|
- **Config fields:** Tailnet, API key
|
|
- **Auth:** Bearer token against `api.tailscale.com`
|
|
- **Actions used:** list devices, remove a device, authorize/deauthorize a device
|
|
- **Required access:** An API access token (or OAuth client) with **Devices Core: Read + Write** — create one under the admin console → Settings → Keys. Read-only isn't enough since remove/authorize are write calls.
|
|
|
|
### Proxmox VE
|
|
|
|
- **Config fields:** Proxmox URL, API token ID, API token secret, allow self-signed certificate
|
|
- **Auth:** `PVEAPIToken=<tokenId>=<tokenSecret>` header
|
|
- **Actions used:** list nodes/VMs/LXCs, read guest config and live status, read node host stats and storage usage, start/stop/reboot/shutdown a guest, read backup job schedules and recent `vzdump` task history
|
|
- **Required access:** A dedicated API token (Datacenter → Permissions → API Tokens) with a role granting **VM.Audit + VM.PowerMgmt** (e.g. `PVEVMAdmin`) on the VMs/LXCs to manage, **plus Sys.Audit and Datastore.Audit** on the node(s) for the host CPU/RAM/storage cards to populate. A token scoped to VM management only will still work for the guest list and power actions — it'll just show an error on the per-node hardware card instead of failing outright. Backup job schedules and run history need that same **Sys.Audit** — no separate permission to grant if the node-stats card already works.
|
|
- **Notes:** self-signed certificates are supported via the "Allow self-signed certificate" checkbox — common for an internal PVE host.
|
|
|
|
### Synology DSM
|
|
|
|
- **Config fields:** Synology DSM URL, Username, Password, allow self-signed certificate
|
|
- **Auth:** DSM session login (`SYNO.API.Auth`), session id reused until it expires
|
|
- **Actions used:** read-only — storage/volume/disk health, system info, network info. No writes.
|
|
- **Required access:** A DSM user account that can view **Storage Manager** and **System Information** (a regular admin-group account is simplest; a dedicated read-only user works too since nothing is ever changed). **2FA/OTP on the account is not supported** — use an account without it enabled, or DSM's application-specific password if your setup requires 2FA elsewhere.
|
|
- **Notes:** works over plain HTTP or HTTPS depending on the URL you enter; self-signed certs supported.
|
|
|
|
### Semaphore (Ansible Semaphore / Semaphore UI)
|
|
|
|
- **Config fields:** Semaphore URL, API token
|
|
- **Auth:** Bearer token
|
|
- **Actions used:** list projects, list templates, run a template (creates a task)
|
|
- **Required access:** A user API token with access to every project you want visible, and **permission to run templates** in those projects — a viewer/guest-level project role can list templates but will fail on "Run", so the account needs at least the operator-equivalent role Semaphore's own project permissions define.
|
|
|
|
### Gitea
|
|
|
|
- **Config fields:** Gitea URL, API token
|
|
- **Auth:** `Authorization: token <token>` header
|
|
- **Actions used:** list repos, list Actions workflow runs, re-run failed jobs in a run
|
|
- **Required access:** A personal access token with **`repo`** scope (read access to repos, including private ones you want tracked) and Actions read/write — generate it under the account → Settings → Applications → Generate New Token, with the `repository` and `write:repository`/Actions permission groups enabled (exact grouping depends on your Gitea version's token scope UI). Read-only Actions access isn't enough since re-running jobs is a write call.
|
|
|
|
### Dockhand
|
|
|
|
- **Config fields:** Dockhand URL, API token
|
|
- **Auth:** Bearer token against Dockhand's own API
|
|
- **Actions used:** list environments/containers, check for image updates, start/stop/restart a container
|
|
- **Required access:** A Dockhand API token belonging to a user with access to every environment (Docker host) you want visible, with permission to **start/stop/restart containers and trigger update checks** in each — not just view them.
|
|
|
|
### Uptime Kuma
|
|
|
|
- **Config fields:** Uptime Kuma URL, username (leave blank — see below), API key
|
|
- **Auth:** HTTP Basic, with the API key as the password and the username left empty. Uptime Kuma has no
|
|
conventional REST API — the dashboard talks to it over Socket.IO — so this integration reads its
|
|
Prometheus-metrics endpoint (`GET /metrics`) instead and parses that. On installs from before the API-key
|
|
feature existed (Uptime Kuma < 1.23), that endpoint instead checks your real dashboard login, so put your
|
|
Uptime Kuma username and password in those two fields rather than leaving the username blank.
|
|
- **Required access:** In Uptime Kuma, go to Settings → API Keys → **Add API Key**, and paste the value it
|
|
shows you (once — it isn't shown again) into this integration's "API key" field. No other permission is
|
|
needed; the metrics endpoint is read-only.
|
|
- **What you get:** every monitor's status (up/down/pending/maintenance), response time, uptime over 24
|
|
hours/30 days, and certificate days remaining where applicable. A monitor is linked to one of your servers
|
|
when its target — an IP, or a TCP/HTTP hostname — matches that server's own address or hostname; monitors
|
|
with no single network target (groups, push monitors, keyword checks with a complex URL) are shown
|
|
unmatched rather than guessed at. Uptime Kuma's tags aren't read, since the metrics endpoint doesn't
|
|
reliably distinguish a tag from any other label.
|
|
- **Maintenance import:** the Maintenance page can read which monitors are currently in maintenance in Uptime
|
|
Kuma and start (or extend) a maintenance window here for the matching server, for a duration you pick — the
|
|
metrics endpoint only exposes current status, not a monitor's scheduled start/end time, so this reflects
|
|
what's in maintenance right now rather than mirroring Uptime Kuma's own schedule.
|
|
|
|
### phpIPAM
|
|
|
|
- **Config fields:** phpIPAM URL, API app ID, App token
|
|
- **Auth:** the `token` header (and `phpipam-token`, in case your version expects that name instead), set to a
|
|
static per-app code. In phpIPAM, go to **Administration → API**, create (or edit) an API app, and set its
|
|
**App security** to **"SSL with App token"** (or "App token" if the install isn't served over HTTPS). Saving
|
|
it shows the app's code once — that's what goes in this integration's "App token" field, and the app's own
|
|
short id (chosen when you created it) goes in "API app ID". phpIPAM's other auth method — logging in as a
|
|
real user to get a short-lived token — isn't supported; use an App-token app instead.
|
|
- **Required access:** the API app just needs read access to whichever sections/subnets you want imported.
|
|
- **What it does:** this is import-only, not a full integration page — on the **IP Addresses** page, "Sync
|
|
from phpIPAM" reads every subnet and the addresses in each, and adds or updates an IPAM entry per address
|
|
(label from its hostname or description, the subnet's own description as its location, description/note/MAC
|
|
folded into notes), the same way "Sync from Tailscale"/"Sync from Proxmox" already work: an address you
|
|
entered by hand, or that a different sync source owns, is never overwritten.
|
|
- **Not verified against a live instance** — built from phpIPAM's own published API documentation
|
|
(endpoints, the `token` header, and the address/subnet field names all cross-checked there), but nobody has
|
|
run it against a real phpIPAM yet. If a sync comes back empty or with the wrong fields, tell us what your
|
|
instance actually returned and we'll adjust.
|
|
|
|
## DNS providers
|
|
|
|
### Cloudflare
|
|
|
|
- **Config fields:** API Token
|
|
- **Auth:** Bearer token against the Cloudflare v4 API
|
|
- **Actions used:** list zones, list/create/update/delete DNS records
|
|
- **Required access:** A scoped API token (My Profile → API Tokens → Create Token) with **Zone → Zone → Read** and **Zone → DNS → Edit**, restricted to the zone(s) you want managed. `DNS Read` alone isn't enough — record add/update/delete need `Edit`.
|
|
|
|
### Loopia
|
|
|
|
- **Config fields:** Username, Password
|
|
- **Auth:** Full account credentials sent on every XML-RPC call — Loopia's API has no scoped API-key concept
|
|
- **Actions used:** list domains/subdomains/zone records, add/remove zone records and subdomains
|
|
- **Required access:** The full Loopia account username and password. There's no way to scope this down at the API level — the credential has the same access as logging into the Loopia customer portal.
|
|
|
|
### Pi-hole
|
|
|
|
- **Config fields:** Pi-hole URL, Web password
|
|
- **Auth:** Session login against the Pi-hole v6 API (`/api/auth`) using the admin web password, session id cached until it expires
|
|
- **Actions used:** read/add/update/delete local DNS "hosts" (A/AAAA) and CNAME records
|
|
- **Required access:** The Pi-hole admin web interface password — Pi-hole v6 doesn't have per-feature roles, so this is effectively full admin access to that Pi-hole instance.
|
|
|
|
### Azure DNS
|
|
|
|
- **Config fields:** Tenant ID, Client (application) ID, Client secret, Subscription ID
|
|
- **Auth:** OAuth2 client-credentials (Azure AD app registration / service principal), then Bearer token against Azure Resource Manager
|
|
- **Actions used:** list DNS zones, list/read/create/update/delete record sets
|
|
- **Required access:** The service principal needs the **DNS Zone Contributor** role (or higher) on the subscription or resource group containing the DNS zone(s) — assign it under Azure Portal → the zone or resource group → Access control (IAM) → Add role assignment.
|
|
|
|
### cPanel
|
|
|
|
- **Config fields:** cPanel URL, Username, API Token, allow self-signed certificate
|
|
- **Auth:** `Authorization: cpanel <username>:<apiToken>` header (UAPI for reads, API 2 for record writes)
|
|
- **Actions used:** list zones/domains, read a zone's records, add/remove a zone record
|
|
- **Required access:** An API token generated under cPanel → Security → Manage API Tokens for the account that **owns** the domain(s) being managed. cPanel tokens inherit the full account's permissions — there's no separate DNS-only scope to grant.
|
|
|
|
### Technitium DNS Server
|
|
|
|
- **Config fields:** Technitium URL, API Token
|
|
- **Auth:** Bearer token
|
|
- **Actions used:** list zones, read zone records, add/delete records (an "update" is implemented as delete + add)
|
|
- **Required access:** A token tied to a Technitium user account with **Zones: View + Modify** permission — view-only will fail on record changes since updates are add/delete calls under the hood.
|