Skip to main content

TAILSCALE EXTENSIONS

Every Swamp extension that covers Tailscale, as published in the registry. Install any of them with swamp extension pull.

Extensions

Extension Version License Contents
@swamp/tailscale 2026.10.13.1 - 25 behavior types
@keeb/tailscale 2026.07.18.1 - 2 behavior types, 1 workflows
@hivemq/tailscale 2026.08.27.1787839823 - 1 behavior types
@mgreten/tailscale-oauth-client 2026.10.14.1 MIT 1 behavior types
@bitgnome/tailscale 2026.06.21.1 - 1 behavior types, 1 workflows
@josephholsten/tailscale/net 2026.06.22.1 - 1 behavior types
@bixu/tailnet-healthcheck 2026.04.23.2 - 1 behavior types
@josephholsten/tailscale/device 2026.06.18.1 - 1 behavior types
@sntxrr/tailscale-acl-drift 2026.10.14.1 MIT -
@sntxrr/tailscale-external-acl-management 2026.10.14.1 MIT -
@sntxrr/tailcat-probe 2026.10.14.1 MIT 1 behavior types
@bixu/tailscale-community 2026.10.13.1 - -

@swamp/tailscale

swamp extension pull @swamp/tailscale

Behavior type @swamp/tailscale/contacts

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
account object {email: string} no The account contact
support object {email: string} no The support contact
security object {email: string} no The security contact
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the contacts from the global arguments -
get Read the current contacts into state -
update Apply the contacts from the global arguments -
delete Stop managing the contacts; Tailscale keeps the current values -
sync Refresh the contacts from Tailscale -
resend_verification_email Resend the verification email for a contact contactType

Data written:

Resource Description
state Contacts state

Behavior type @swamp/tailscale/device

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
get Get a device by ID id
delete Delete the device from the tailnet id
list List devices in the tailnet and write each to state -
adopt Adopt an existing device by ID into managed state id, expected_name (optional)
expire Expire the device's node key, forcing it to re-authenticate id
set_name Set the device's machine name id, name
set_ipv4_address Set the device's Tailscale IPv4 address id, ipv4

Data written:

Resource Description
state Device state

Behavior type @swamp/tailscale/device-authorization

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
authorized boolean no - If true, authorize a new device or re-authorize a previously deauthorized device. - If false, deauthorize an authorized device.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the device authorization from the global arguments -
get Read the current device authorization into state -
update Apply the device authorization from the global arguments -
delete Stop managing the device authorization; Tailscale keeps the current values -
sync Refresh the device authorization from Tailscale -

Data written:

Resource Description
state Device authorization state

Behavior type @swamp/tailscale/device-invite

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this device invite, used as the unique identifier in the factory pattern
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
multiUse boolean no Whether the invite can be accepted more than once. When set to true, it results in an invite that can be accepted up to 1,000 times.
allowExitNode boolean no Whether the invited user can use the device as an exit node when it advertises as one.
email string no The email to send the created invite to. If not set, the endpoint generates and returns an invite URL (but doesn't send it out).
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create a device invite -
get Get a device invite by ID id
delete Delete the device invite id (optional)
sync Refresh the stored device invite from Tailscale -
list List device invites and write each to state -
adopt Adopt an existing device invite by ID into managed state id
resend Resend the invitation email -

Data written:

Resource Description
state Device invite state

Behavior type @swamp/tailscale/device-key

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
keyExpiryDisabled boolean no - If true, disable the device's key expiry. The original key expiry time is still maintained. Upon re-enabling, the key will expire at that original time. - If false, enable the device's key expiry. Sets the key to expire at the original expiry time prior to disabling. The key may already have expired. In that case, the device must be re-authenticated.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the device key from the global arguments -
get Read the current device key into state -
update Apply the device key from the global arguments -
delete Clear the device key -
sync Refresh the device key from Tailscale -

Data written:

Resource Description
state Device key state

Behavior type @swamp/tailscale/device-posture-attribute

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
attributeKey string yes The name of the posture attribute to set. This must be prefixed with custom: Keys have a maximum length of 128 characters including the namespace, and can only contain letters, numbers, underscores, and colon. Keys are case-sensitive. Keys must be unique, but are checked for uniqueness in a case-insensitive manner. For example, custom:MyAttribute and custom:myattribute cannot both be set within a single tailnet. All values for a given key need to be of the same type, which is determined when the first value is written for a given key. For example, custom:myattribute cannot have a numeric value (87) for one node and a string value ("78") for another node within the same tailnet.
value string | number | boolean no A value can be either a string, number or boolean. A string value can have a maximum length of 50 characters, and can only contain letters, numbers, underscores, and periods. A number value is an integer and must be a JSON safe number (up to 2^53 - 1).
expiry string no An optional expiry time for a given posture attribute. If set, Tailscale will automatically remove the attribute within a few minutes after the specified time.
comment string no An optional comment indicating a reason why an attribute is set, which will be added to the audit log.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the device posture attribute from the global arguments -
get Read the current device posture attribute into state -
update Apply the device posture attribute from the global arguments -
delete Delete the device posture attribute -
sync Refresh the device posture attribute from Tailscale -

Data written:

Resource Description
state Device posture attribute state

Behavior type @swamp/tailscale/device-subnet-routes

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
routes array of string no The new list of enabled subnet routes.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the device subnet routes from the global arguments -
get Read the current device subnet routes into state -
update Apply the device subnet routes from the global arguments -
delete Clear the device subnet routes -
sync Refresh the device subnet routes from Tailscale -

Data written:

Resource Description
state Device subnet routes state

Behavior type @swamp/tailscale/device-tags

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
deviceId string yes ID of the device. Using the device's nodeId is preferred, but its numeric id value can also be used.
tags array of string no The new list of tags for the device.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the device tags from the global arguments -
get Read the current device tags into state -
update Apply the device tags from the global arguments -
delete Clear the device tags -
sync Refresh the device tags from Tailscale -

Data written:

Resource Description
state Device tags state

Behavior type @swamp/tailscale/dns-configuration

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
nameservers array of object {address?: string, useWithExitNode?: boolean} no Global DNS resolvers to use. If preferences.overrideLocalDNS is true, these override the local OS configuration; otherwise they are used as fallback resolvers.
splitDNS object no Map of DNS name suffixes (domains) to lists of resolvers for Split DNS and advanced routing overlays.
searchPaths array of string no Search domain paths to apply.
preferences object {overrideLocalDNS?: boolean, magicDNS?: boolean} no -
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the DNS configuration from the global arguments -
get Read the current DNS configuration into state -
update Apply the DNS configuration from the global arguments -
delete Clear the DNS configuration -
sync Refresh the DNS configuration from Tailscale -

Data written:

Resource Description
state DNS configuration state

Behavior type @swamp/tailscale/dns-nameservers

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
dns array of string no DNS nameservers.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the DNS nameservers from the global arguments -
get Read the current DNS nameservers into state -
update Apply the DNS nameservers from the global arguments -
delete Clear the DNS nameservers -
sync Refresh the DNS nameservers from Tailscale -

Data written:

Resource Description
state DNS nameservers state

Behavior type @swamp/tailscale/dns-preferences

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
magicDNS boolean no Whether MagicDNS is active for this tailnet.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the DNS preferences from the global arguments -
get Read the current DNS preferences into state -
update Apply the DNS preferences from the global arguments -
delete Clear the DNS preferences -
sync Refresh the DNS preferences from Tailscale -

Data written:

Resource Description
state DNS preferences state

Behavior type @swamp/tailscale/dns-search-paths

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
searchPaths array of string no The search domains for the given tailnet.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the DNS search paths from the global arguments -
get Read the current DNS search paths into state -
update Apply the DNS search paths from the global arguments -
delete Clear the DNS search paths -
sync Refresh the DNS search paths from Tailscale -

Data written:

Resource Description
state DNS search paths state

Behavior type @swamp/tailscale/dns-split-nameservers

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
domain string yes The split-DNS domain this model manages
nameservers array of string no Nameservers that resolve the domain
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the split DNS nameservers from the global arguments -
get Read the current split DNS nameservers into state -
update Apply the split DNS nameservers from the global arguments -
delete Clear the split DNS nameservers -
sync Refresh the split DNS nameservers from Tailscale -

Data written:

Resource Description
state Split DNS nameservers state

Behavior type @swamp/tailscale/federated-identity

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this federated identity, used as the unique identifier in the factory pattern
description string no A short string specifying the purpose of the key. Can be a maximum of 50 alphanumeric characters. Hyphens and spaces are also allowed.
scopes array of string no A list of scopes to grant to the key. At least one scope is required for OAuth clients and federated identities. See trust credentials scopes for a list of available scopes. Only applies to OAuth clients and federated identities.
tags array of string no A list of tags associated to the trust credential. Auth keys created with this credential must have these exact tags, or tags owned by the credential's tags. Mandatory if the scopes include "devices:core" or "auth_keys". Only applies to OAuth clients and federated identities.
issuer string no The issuer of the OIDC identity token used in the token exchange. Must be a valid and publicly reachable https:// URL. Only applies to federated identities.
subject string no The pattern used when matching against the sub claim from an OIDC identity token. Patterns can include * characters to match against any character. Only applies to federated identities.
audience string no The value used when matching against the aud claim from an OIDC identity token. Specifying the audience is optional as Tailscale will generate a secure audience at creation time by default. It is recommended to let Tailscale generate the audience unless the identity provider you are integrating with requires a specific audience format. Only applies to federated identities.
customClaimRules object no A map of claim names to pattern strings used to match against arbitrary claims in the OIDC identity token. Patterns can include * characters to match against any character. Only applies to federated identities.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create a federated identity -
get Get a federated identity by ID id
update Update the federated identity from the global arguments -
delete Delete the federated identity id (optional)
sync Refresh the stored federated identity from Tailscale -
list List federated identitys and write each to state -
adopt Adopt an existing federated identity by ID into managed state id

Data written:

Resource Description
state Federated identity state

Behavior type @swamp/tailscale/log-stream

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
destinationType "splunk" | "elastic" | "panther" | "cribl" | "crowdstrike" | "datadog" | "axiom" | "s3" no The type of system to which logs are being streamed.
url string no The URL to which log streams are being posted. If the DestinationType is s3, the URL may be (and often is) empty to use the official Amazon S3 endpoint.
user string no The username with which log streams to this endpoint are authenticated.
uploadPeriodMinutes integer no An optional number of minutes to wait in between uploading new logs. If the quantity of logs does not fit within a single upload, multiple uploads will be made.
compressionFormat "zstd" | "gzip" | "none" no The compression algorithm with which to compress logs. none disables compression. Defaults to none.
token string no The token/password with which log streams to this endpoint should be authenticated.
s3Bucket string no The S3 bucket name. Required if the destinationType is s3.
s3Region string no The region in which the S3 bucket is located. Required if the destinationType is s3.
s3KeyPrefix string no An optional S3 key prefix to prepend to the auto-generated S3 key name.
s3AuthenticationType "accesskey" | "rolearn" no What type of authentication to use for S3. Required if the destinationType is s3. Tailscale recommends using rolearn. See Amazon documentation.
s3AccessKeyId string no The S3 access key ID. Required if the destinationType is s3 and authenticationType is accesskey.
s3SecretAccessKey string no The S3 secret access key. Required if the destinationType is s3 and authenticationType is accesskey.
s3RoleArn string no The Role ARN that Tailscale should supply to AWS when authenticating using role-based authentication. Required if the destinationType is s3 and authenticationType is rolearn.
gcsBucket string no The GCS bucket name. Required if the destinationType is gcs.
gcsKeyPrefix string no An optional GCS key prefix to append to the GCS bucket name.
gcsScopes array of string no The GCS scopes needed to be able to write to the GCS bucket.
gcsCredentials string no The JSON workload identity credentials from GCS needed for accessing the GCS account.
logType "configuration" | "network" yes The type of log.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create the log stream; fails if one already exists for logType -
get Get the log stream for logType and write it to state -
update Update the log stream from the global arguments -
delete Delete the log stream -
sync Refresh the log stream from Tailscale -

Data written:

Resource Description
state Log stream state

Behavior type @swamp/tailscale/oauth-app

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
instanceName string yes Instance name for this OAuth app, used as the unique identifier in the factory pattern
name string no The name of the OAuth app. Must be between 3 and 50 characters and contain only alphanumeric characters, dashes, periods, and underscores.
description string no A human-readable description of the OAuth app. Must be at most 300 characters.
redirectURIs array of string no The list of permitted redirect URIs for the OAuth authorization code flow. At least one redirect URI is required. Each URI must use the https scheme, except for localhost, 127.0.0.1, and ::1, which may use any scheme. Raw IP address hosts are not permitted.
scopes array of string no The list of OAuth scopes granted to the app. Must be non-empty. Learn more about OAuth clients and scopes.
allowedNodeAttributes array of string no The list of custom device attributes that the OAuth app is allowed to set.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create an OAuth app -
get Get an OAuth app by ID id
update Update the OAuth app from the global arguments -
delete Delete the OAuth app id (optional)
sync Refresh the stored OAuth app from Tailscale -
list List OAuth apps and write each to state -
lookup Find an existing OAuth app by name and write it to state -
adopt Adopt an existing OAuth app by ID into managed state id, expected_name (optional)

Data written:

Resource Description
state OAuth app state
secret Secrets returned only when the OAuth app is created (or its secret rotated). Stored in a vault.

Behavior type @swamp/tailscale/oauth-client

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this OAuth client, used as the unique identifier in the factory pattern
description string no A short string specifying the purpose of the key. Can be a maximum of 50 alphanumeric characters. Hyphens and spaces are also allowed.
scopes array of string no A list of scopes to grant to the key. At least one scope is required for OAuth clients and federated identities. See trust credentials scopes for a list of available scopes. Only applies to OAuth clients and federated identities.
tags array of string no A list of tags associated to the trust credential. Auth keys created with this credential must have these exact tags, or tags owned by the credential's tags. Mandatory if the scopes include "devices:core" or "auth_keys". Only applies to OAuth clients and federated identities.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create an OAuth client -
get Get an OAuth client by ID id
update Update the OAuth client from the global arguments -
delete Delete the OAuth client id (optional)
sync Refresh the stored OAuth client from Tailscale -
list List OAuth clients and write each to state -
adopt Adopt an existing OAuth client by ID into managed state id

Data written:

Resource Description
state OAuth client state
secret Secrets returned only when the OAuth client is created (or its secret rotated). Stored in a vault.

Behavior type @swamp/tailscale/policy-file

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
policy string no The policy file as HuJSON (JSON with comments and trailing commas)
overwriteExistingContent boolean no Let create replace a policy file that has been edited since the tailnet was created
resetOnDelete boolean no Reset the policy file to the default when the model is deleted
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Replace the policy file; refuses to overwrite an edited policy unless overwriteExistingContent is set -
get Read the current policy file into state -
update Replace the policy file; refuses if it changed since the last get or sync -
delete Stop managing the policy file; resets it to the default only when resetOnDelete is set -
sync Refresh the policy file from Tailscale -
preview Preview which rules in the policy match a user or an IP:port type (optional), previewFor (optional)
validate Validate the policy and run its tests without saving it -

Data written:

Resource Description
state Policy file state
result The response of the most recent run of each action that returns data

Behavior type @swamp/tailscale/posture-integration

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this posture integration, used as the unique identifier in the factory pattern
provider "falcon" | "intune" | "jamfpro" | "kandji" | "kolide" | "sentinelone" no The device posture provider. Required on POST requests, ignored on PATCH requests.
cloudId string no Identifies which of the provider's clouds to integrate with. - For CrowdStrike Falcon, it will be one of us-1, us-2, eu-1 or us-gov. - For Microsoft Intune, it will be one of global or us-gov. - For Jamf Pro, Kandji and Sentinel One, it is the FQDN of your subdomain, for example mydomain.sentinelone.net. - For Kolide, this is left blank.
clientId string no Unique identifier for your client. - For Microsoft Intune, it will be your application's UUID. - For CrowdStrike Falcon and Jamf Pro, it will be your client id. - For Kandji, Kolide and Sentinel One, this is left blank.
tenantId string no The Microsoft Intune directory (tenant) ID. For other providers, this is left blank.
clientSecret string no The secret (auth key, token, etc.) used to authenticate with the provider. Required when creating a new integration, may be omitted when updating an existing integration, in which case we retain the existing password.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create a posture integration -
get Get a posture integration by ID id
update Update the posture integration from the global arguments -
delete Delete the posture integration id (optional)
sync Refresh the stored posture integration from Tailscale -
list List posture integrations and write each to state -
adopt Adopt an existing posture integration by ID into managed state id

Data written:

Resource Description
state Posture integration state

Behavior type @swamp/tailscale/service

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
addrs array of string no The IP addresses assigned to the Service: the IPv4 followed by the IPv6.
name string yes The unique name of the Service.
displayName string no An optional human-readable label for the Service, shown in the Tailscale admin console and to clients with access to the Service. Must be 64 characters or fewer.
comment string no An optional comment for the Service.
ports array of string no A list of protocol:port pairs to be exposed by the Service. The only supported protocol is "tcp" at this time. "do-not-validate" can be used to skip validation.
tags array of string no A list of optional tags associated with the Service.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create the service; fails if one already exists for name -
get Get the service for name and write it to state -
update Update the service from the global arguments -
delete Delete the service -
sync Refresh the service from Tailscale -
list List services and write each to state -
list_devices List the devices hosting the service -
get_device_approval Get whether a device is approved to host the service deviceId
set_device_approval Approve or unapprove a device to host the service deviceId, approved (optional)

Data written:

Resource Description
state Service state
result The response of the most recent run of each action that returns data

Behavior type @swamp/tailscale/tailnet-key

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this auth key, used as the unique identifier in the factory pattern
description string no A short string specifying the purpose of the key. Can be a maximum of 50 alphanumeric characters. Hyphens and spaces are also allowed.
capabilities object {devices?: object {create?: object {reusable?: boolean, ephemeral?: boolean, preauthorized?: boolean, tags?: array}}} no capabilities is a mapping of resources to permissible actions.
expirySeconds integer no Specifies the duration in seconds until the key expires. Defaults to 90 days if not supplied. Only applies to auth keys.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create an auth key -
get Get an auth key by ID id
delete Delete the auth key id (optional)
sync Refresh the stored auth key from Tailscale -
list List auth keys and write each to state -
adopt Adopt an existing auth key by ID into managed state id

Data written:

Resource Description
state Auth key state
secret Secrets returned only when the auth key is created (or its secret rotated). Stored in a vault.

Behavior type @swamp/tailscale/tailnet-settings

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
aclsExternallyManagedOn boolean | null no Prevents users from editing policies in the admin console to avoid conflicts with external management workflows like GitOps or Terraform.
aclsExternalLink string no Link to the external tailnet policy definition or management solution for this tailnet.
devicesApprovalOn boolean | null no Whether device approval is enabled for the tailnet.
devicesAutoUpdatesOn boolean | null no Whether auto updates are enabled for devices that belong to this tailnet.
devicesKeyDurationDays integer no The key expiry duration for devices on this tailnet.
usersApprovalOn boolean | null no Whether user approval is enabled for this tailnet.
usersRoleAllowedToJoinExternalTailnets "none" | "admin" | "member" no Which user roles are allowed to join external tailnets.
networkFlowLoggingOn boolean | null no Whether network flog logs are enabled for the tailnet.
routeSelection "active-passive-failover" | "regional-routing" | "regional-routing-failover" | "magicroute" no The route selection algorithm used by the tailnet: * active-passive-failover - Active-passive failover (formerly known as "Failover") * regional-routing - Regional routing * regional-routing-failover - Regional routing with in-region failover * magicroute - MagicRoute A PATCH request must not specify both the regionalRoutingOn and routeSelection fields.
postureIdentityCollectionOn boolean | null no Whether identity collection is enabled for device posture integrations for the tailnet.
httpsEnabled boolean | null no Whether provisioning of HTTPS certificates is enabled for this tailnet.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Apply the tailnet settings from the global arguments -
get Read the current tailnet settings into state -
update Apply the tailnet settings from the global arguments -
delete Stop managing the tailnet settings; Tailscale keeps the current values -
sync Refresh the tailnet settings from Tailscale -

Data written:

Resource Description
state Tailnet settings state

Behavior type @swamp/tailscale/user

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
get Get an user by ID id
delete Delete the user from the tailnet id
list List users in the tailnet and write each to state -
adopt Adopt an existing user by ID into managed state id, expected_name (optional)
set_role Change the user's role id, role (optional)
approve Approve a user waiting for approval id
suspend Suspend the user id
restore Restore a suspended user id

Data written:

Resource Description
state User state

Behavior type @swamp/tailscale/user-invite

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this user invite, used as the unique identifier in the factory pattern
role "member" | "admin" | "it-admin" | "network-admin" | "billing-admin" | "auditor" no Optionally specifies a user role to assign the invited user.
email string no Optionally specifies the email to send the created invite. If not set, the endpoint generates and returns an invite URL, but does not email it out.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create an user invite -
get Get an user invite by ID id
delete Delete the user invite id (optional)
sync Refresh the stored user invite from Tailscale -
list List user invites and write each to state -
adopt Adopt an existing user invite by ID into managed state id
resend Resend the invitation email -

Data written:

Resource Description
state User invite state

Behavior type @swamp/tailscale/webhook

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
name string yes Instance name for this webhook, used as the unique identifier in the factory pattern
endpointUrl string no The endpoint that events are sent to from Tailscale via POST requests.
providerType "slack" | "mattermost" | "googlechat" | "discord" no The provider type for the webhook destination, or an empty string if none are applicable. Outgoing webhook events are sent in the format expected by the provider type if non-empty.
subscriptions array of "nodeCreated" | "nodeNeedsApproval" | "nodeApproved" | "nodeKeyExpiringInOneDay" | "nodeKeyExpired" | "nodeDeleted" | "nodeSigned" | "nodeNeedsSignature" | "policyUpdate" | "userCreated" | "userNeedsApproval" | "userSuspended" | "userRestored" | "userDeleted" | "userApproved" | "userRoleUpdated" | "subnetIPForwardingNotEnabled" | "exitNodeIPForwardingNotEnabled" no The list of subscribed events that trigger POST requests to the configured endpoint URL. Learn more about webhook events.
apiKey string no Tailscale API access token. Overrides the TAILSCALE_API_KEY environment variable. Wire with a vault.get(...) expression.
oauthClientId string no OAuth client ID, used with oauthClientSecret instead of an API key. Overrides TAILSCALE_OAUTH_CLIENT_ID.
oauthClientSecret string no OAuth client secret. Overrides TAILSCALE_OAUTH_CLIENT_SECRET. Wire with a vault.get(...) expression.
oauthScopes array of string no Scopes to request when exchanging the OAuth client credentials; defaults to all of the client's scopes.
tailnet string no Tailnet ID. Defaults to TAILSCALE_TAILNET, then '-' (the tailnet of the credential in use).
baseUrl string no Tailscale API base URL. Defaults to TAILSCALE_BASE_URL, then https://api.tailscale.com.

Methods, run with swamp behavior run:

Method Description Arguments
create Create a webhook -
get Get a webhook by ID id
update Update the webhook from the global arguments -
delete Delete the webhook id (optional)
sync Refresh the stored webhook from Tailscale -
list List webhooks and write each to state -
adopt Adopt an existing webhook by ID into managed state id
test Send a test event to the webhook endpoint -
rotate_secret Rotate the webhook's signing secret and store the new secret -

Data written:

Resource Description
state Webhook state
secret Secrets returned only when the webhook is created (or its secret rotated). Stored in a vault.

@keeb/tailscale

swamp extension pull @keeb/tailscale

Behavior type @keeb/tailscale/net

Global arguments, set with --global-arg on swamp behavior create:

None.

Methods, run with swamp behavior run:

Method Description Arguments
sync Parse tailscale status JSON and write a named resource per machine statusJson

Data written:

Resource Description
machine Tailnet machine

Behavior type @keeb/tailscale/node

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
sshHost string yes SSH hostname/IP of the target VM (set via CEL from testVm)
sshUser string no SSH user (default 'root')

Methods, run with swamp behavior run:

Method Description Arguments
install Install Tailscale on an Alpine VM, start the daemon, and authenticate authKey

Data written:

Resource Description
result Tailscale install result

Workflows in @keeb/tailscale

Workflow Description
@keeb/setup-tailscale Install Tailscale and authenticate on a running VM by name

@hivemq/tailscale

swamp extension pull @hivemq/tailscale

Behavior type @hivemq/tailscale

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
hosts array of object {name: string, address: string, tags: array of string, user?: string} yes Static host inventory for this instance. Methods select subsets via includeTags/excludeTags.
privateKey string yes PEM private key body used for every host in this instance. One credential per model instance.
defaultUser string no SSH user when the per-host entry doesn't override it
connectTimeoutSeconds number no -
commandTimeoutSeconds number no -
advertiseTags string yes Tailscale advertise tag for this fleet (e.g. 'tag:harvester-dev'). Used by bringUp + verify.
tailscaleApiKey string no Tailscale API key (Bearer token) for verifyAcl. Optional unless verifyAcl is called.
ansibleRoleDefaultsPath string no Path to the Ansible role defaults file holding tailscale_version + tailscale_sha256_amd64 pins.

Methods, run with swamp behavior run:

Method Description Arguments
install Install pinned Tailscale version on every selected host (sequential, fail-fast). Idempotent — hosts already at the pinned version are skipped. selector, tailscaleVersion (optional), tailscaleSha256 (optional)
bringUp Run tailscale up on every selected host (sequential, fail-fast). Skips hosts already joined with the right tag if Tailscale SSH works. selector, authKey
bootstrap Install + bringUp on every selected host (sequential, fail-fast). Equivalent to install then bringUp. selector, authKey, tailscaleVersion (optional), tailscaleSha256 (optional)
prepareCanary bootstrap + verify for a canary host subset (sequential, fail-fast). Safe pre-approval step: brings up the canary hosts and confirms they are healthy before operator approves fleet rollout. selector, authKey, tailscaleVersion (optional), tailscaleSha256 (optional)
prepareFleet bootstrap + verify + verifyAcl for the fleet (sequential, fail-fast). Run after operator approves canary. Combines all safe pre-harden steps into one workflow job. selector, authKey, tailscaleVersion (optional), tailscaleSha256 (optional)
verify Read-only verify: every selected host shows Running, advertises the configured tag, and Tailscale SSH works. Throws on first failure. selector
verifyAcl Fetch the tailnet ACL via the Tailscale API and confirm an action:accept SSH rule covers the configured advertiseTag (and no action:check rule, which would require browser auth). tailnetTag (optional)
harden Disable password + KbdInteractive auth in sshd on every selected host (sequential, fail-fast). Refuses unless break-glass public key is present in BOTH harvester-admin and rancher authorized_keys AND Tailscale SSH works. selector, breakGlassPublicKey

Data written:

Resource Description
hostState Per-host Tailscale rollout state (factory: one resource per host)
aclState Tailscale ACL policy snapshot for the configured advertiseTag

@mgreten/tailscale-oauth-client

swamp extension pull @mgreten/tailscale-oauth-client

Behavior type @mgreten/tailscale-oauth-client

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
managerClientId string yes -
managerClientSecret string yes -
timeoutSeconds integer no -

Methods, run with swamp behavior run:

Method Description Arguments
previewCreate Persist a no-network candidate preview requestId, description, scopes, tags
createCandidate Create and vault one exactly journaled candidate requestId, description, scopes, tags, confirmation
verifyCandidate Verify full configured candidate OAuth issuance requestId
previewCutover Preview recording verified operator cutover evidence requestId, candidateRequestId, candidateId, evidence
recordCutover Persist immutable verified cutover evidence requestId, candidateRequestId, candidateId, evidence, confirmation
previewRevoke Preview exact irreversible prior-client revocation requestId, candidateRequestId, candidateId, previousClientId
revokePrevious Preflight and journal exact previous-client revocation requestId, candidateRequestId, candidateId, previousClientId, confirmation
syncCandidate Refresh candidate metadata or provider absence requestId

Data written:

Resource Description
createPreview Bound candidate-creation preview
candidateCreationAttempt Durable non-secret creation journal
candidateMetadata Non-secret candidate OAuth-client state
candidateCredential Vaulted one-time candidate credential
verificationReceipt Non-secret OAuth issuance verification
cutoverPreview Bound non-secret cutover preview
cutoverReceipt Operator-recorded cutover evidence
revokePreview Bound irreversible-revocation preview
revocationAttempt Durable non-secret revocation journal
revocationReceipt Non-secret prior-client revocation receipt

@bitgnome/tailscale

swamp extension pull @bitgnome/tailscale

Behavior type @bitgnome/tailscale/net

Global arguments, set with --global-arg on swamp behavior create:

None.

Methods, run with swamp behavior run:

Method Description Arguments
sync Parse tailscale status JSON and write a named resource per machine statusJson

Data written:

Resource Description
machine Tailnet machine

Workflows in @bitgnome/tailscale

Workflow Description
@bitgnome/setup-tailscale Install Tailscale on hosts of an existing @swamp/ssh fleet and join them to the tailnet using an auth key resolved from a vault. Idempotent — once joined, tailscaled reconnects on every boot; re-run after rebuilding a host. The auth key is read via vault.get and forwarded over the SSH env (AcceptEnv TS_AUTHKEY) so it never lands in argv or Swamp's persisted run data. Requires (in the consuming repo): - an @swamp/ssh model instance whose name you pass as sshModel, and - a vault named tailscale-secrets holding the key TS_AUTHKEY.

@josephholsten/tailscale/net

swamp extension pull @josephholsten/tailscale/net

Behavior type @josephholsten/tailscale/net

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
tailnet string yes Tailnet name (e.g. 'example.com') or '-' for the default tailnet of the authenticated user
apiKey string yes Tailscale API key (tskey-api-...)

Methods, run with swamp behavior run:

Method Description Arguments
sync Read all devices from the Tailscale API and write one device resource per entry. -
delete Remove a device from the tailnet by nodeId. Run sync first to discover nodeId values. nodeId

Data written:

Resource Description
device Tailscale device in the tailnet

@bixu/tailnet-healthcheck

swamp extension pull @bixu/tailnet-healthcheck

Behavior type @bixu/tailnet-healthcheck

Global arguments, set with --global-arg on swamp behavior create:

None.

Methods, run with swamp behavior run:

Method Description Arguments
run Run a tailnet health report by type and optionally send to Slack -

Data written:

Resource Description
outdatedClients Devices running Tailscale client versions below the minimum safe version

@josephholsten/tailscale/device

swamp extension pull @josephholsten/tailscale/device

Behavior type @josephholsten/tailscale/device/serve

Global arguments, set with --global-arg on swamp behavior create:

None.

Methods, run with swamp behavior run:

Method Description Arguments
set Idempotently add a TCP serve rule. Throws if localPort is already bound to a different target — call unset first. localPort, targetHost, targetPort
unset Remove a TCP serve rule by localPort. No-op if the rule does not exist. localPort
sync Read active TCP serve rules from tailscale serve status --json and write one serve-rule resource per rule. -

Data written:

Resource Description
serve-rule Active Tailscale TCP serve rule on this device

@sntxrr/tailscale-acl-drift

swamp extension pull @sntxrr/tailscale-acl-drift

@sntxrr/tailscale-external-acl-management

swamp extension pull @sntxrr/tailscale-external-acl-management

@sntxrr/tailcat-probe

swamp extension pull @sntxrr/tailcat-probe

Behavior type @sntxrr/tailcat/probe

Global arguments, set with --global-arg on swamp behavior create:

Name Type Required Description
target string yes Non-secret label for the server, recorded in every result.
tailcatBinary string no Path to the tailcat binary.
derpmapUrl string no Custom DERP map URL, for self-hosted relays.
timeoutSeconds number no Hard ceiling on any single tailcat run.

Methods, run with swamp behavior run:

Method Description Arguments
ping Disco-ping the server once (or until a direct path appears) and untilDirect (optional), timeoutSeconds (optional)
perf Run a bounded throughput test and record a fixed-size summary: udp (optional), direction (optional), seconds (optional), parallel (optional), bitrate (optional), viaDerp (optional), pathTimeoutSeconds (optional)
transfer Send a local file to, or fetch one from, a server running direction, remotePath (optional), maxHashBytes (optional)
exec Run one non-interactive command over tailcat ssh and record its command, user (optional), captureStdoutBytes (optional)

Data written:

Resource Description
ping Reachability and path (direct or DERP) to one server
perf Throughput, RTT and jitter summary of one perf run — no per-second samples
transfer Size and hash of one file sent or received — never its body
exec Exit code, size and hash of one remote command's output

@bixu/tailscale-community

swamp extension pull @bixu/tailscale-community