Documentation
¶
Overview ¶
Package tools defines tailkeeper's tools. M1 contains the read tools for the Tailscale API and the node's local CLI (spec §6, §18).
Index ¶
- func CheckPatchSubjects(env *registry.Env, patch []byte) error
- func CheckProposalSubjects(env *registry.Env, text string) error
- func IsLiteralLogin(s string) bool
- func Register(r *registry.Registry)
- func SubstituteSubjects(ctx context.Context, r *SubjectResolver, text []byte) (out []byte, replaced int, err error)
- type ACLChange
- type ACLChangeCounts
- type ACLDiffInput
- type ACLDiffOutput
- type ACLDiffSide
- type ACLFieldDelta
- type ACLGetInput
- type ACLGetOutput
- type ACLHistoryInput
- type ACLHistoryOutput
- type ACLProblem
- type ACLSSHTestInput
- type ACLSSHVerdict
- type ACLSectionRow
- type ACLSummary
- type ACLTestInput
- type ACLTestOutput
- type ACLTestResult
- type ACLTestVerdict
- type ACLValidateInput
- type ACLValidateOutput
- type ACLVersion
- type Acceptor
- type AuditActor
- type AuditEntry
- type AuditLogInput
- type AuditLogOutput
- type AuditTarget
- type AuthKeyCaps
- type Connectivity
- type Contact
- type ContactsOutput
- type DNSAnswer
- type DNSNodeAttr
- type DNSOutput
- type DNSQueryInput
- type DNSQueryOutput
- type DNSResolverAttr
- type Device
- type DeviceInvite
- type DeviceInvitesOutput
- type DevicePostureOutput
- type DeviceRef
- type DeviceRoutesInput
- type DeviceRoutesOutput
- type DevicesListInput
- type DevicesListOutput
- type Distro
- type ExtraDNSRecord
- type FailureKind
- type FailureLine
- type Flow
- type FlowLogsInput
- type FlowLogsOutput
- type FlowRecord
- type IDRef
- type InviteRef
- type Key
- type KeyRef
- type KeysListOutput
- type LocalDNSStatusOutput
- type LocalIPInput
- type LocalIPOutput
- type LocalIdentity
- type LocalPeer
- type LocalStatusInput
- type LocalStatusOutput
- type LockStatusOutput
- type LogStreamConfig
- type LogStreamInput
- type LogStreamOutput
- type LogStreamStatus
- type Login
- type Metric
- type MetricsOutput
- type NetcheckOutput
- type NoInput
- type OAuthApp
- type OAuthAppsOutput
- type PingInput
- type PingOutput
- type PingReply
- type PingResult
- type Policy
- type PolicyProbe
- type PostureAttribute
- type PostureIntegration
- type PostureIntegrationsOutput
- type PostureStatus
- type Pref
- type PrefsOutput
- type ProbeStatus
- type Resolver
- type RoutePeer
- type ServeEntry
- type ServeOutput
- type Service
- type ServiceRef
- type ServicesOutput
- type Settings
- type SettingsOutput
- type SplitDomain
- type SubjectResolver
- func (SubjectResolver) Format(f fmt.State, _ rune)
- func (r *SubjectResolver) Hide(text string) string
- func (r *SubjectResolver) HideError(err error) error
- func (r *SubjectResolver) Resolve(ctx context.Context, ref string) (Login, error)
- func (r *SubjectResolver) Shown(named bool) acl.Show
- func (r *SubjectResolver) Typed(values ...string)
- type Supports
- type SyspolicyOutput
- type User
- type UserInvite
- type UserInvitesOutput
- type UserRef
- type UsersListInput
- type UsersListOutput
- type VersionOutput
- type Webhook
- type WebhookRef
- type WebhooksOutput
- type WhoisInput
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckPatchSubjects ¶ added in v0.6.0
CheckPatchSubjects applies the subject rule to RFC 6902 patch operations given over MCP: the whole patch is read as one HuJSON document, and no string in it, outside comments, key or value, in a path, a from or a value, in any operation, may be a user login. The errors are those of CheckProposalSubjects, and the pointers are those of the patch (/2/value/src/0 is the third operation's value). Whether the text is a well-formed patch is for hujson.Patch to say when the patch is applied.
Check the exact bytes you will send, and check them before you replace a pseudonym by the login it names: the text after the replacement holds a literal login by design.
func CheckProposalSubjects ¶ added in v0.6.0
CheckProposalSubjects applies the subject rule to a policy text given over MCP: while masking is on, no string of it, outside comments, key or value, may be a user login. It is nil when the rule holds or personalData is show, filter_refused naming the JSON pointers when it does not, and validation_failed when the text nests deeper than 1,000 levels or is not valid HuJSON (it is never a pass for text it could not read).
Check the exact bytes you will send, and check them before you replace a pseudonym by the login it names: the text after the replacement holds a literal login by design.
func IsLiteralLogin ¶ added in v0.6.0
IsLiteralLogin reports whether s holds a user login as the masker reads one: the masker would change it, unless it is one of the three forms that are not logins. A masked value carrying a pseudonym is not a literal login, and neither is a synced group's name.
func SubstituteSubjects ¶ added in v0.6.0
func SubstituteSubjects(ctx context.Context, r *SubjectResolver, text []byte) (out []byte, replaced int, err error)
SubstituteSubjects replaces each pseudonym carrier in text (a policy, or the operations of a patch, as HuJSON; keys and values, never comments) by the login it names, keeping every other byte, and returns how many strings it replaced. A carrier is a string that is exactly "p:xxxxxxxxxx", "[p:xxxxxxxxxx]", or "<masked address> [p:xxxxxxxxxx]" where the masked address contains "…@". A string that holds a pseudonym marker and is none of these, a pseudonym in a patch's path or from, more than maxSubjects distinct pseudonyms, a text whose strings or comments do not end, and a pseudonym that resolves to zero or several users are validation_failed, and none of them sends a request for the users unless the text was fine up to the lookup. When nothing is replaced the result is a copy of text.
Run CheckProposalSubjects or CheckPatchSubjects on the same bytes first: the output holds literal logins by design, and the subject rule would refuse it.
Types ¶
type ACLChange ¶ added in v0.6.0
type ACLChange struct {
Class string `json:"class" jsonschema:"defaults, testsReduced, widening, tailscaleWritten or semantic"`
Op string `json:"op" jsonschema:"added, removed or changed"`
Section string `` /* 162-byte string literal not displayed */
Entry string `json:"entry,omitempty" tk:"untrusted,emails" jsonschema:"the entry's key, or a summary of the rule or assertion"`
Old string `json:"old,omitempty" tk:"untrusted,emails" jsonschema:"the entry on the old side, in canonical form"`
New string `json:"new,omitempty" tk:"untrusted,emails" jsonschema:"the entry on the new side, in canonical form"`
Truncated bool `json:"truncated,omitempty" jsonschema:"old or new was cut at 1 KiB"`
OldCount int `json:"oldCount,omitempty" jsonschema:"how many times a repeated entry (a test) is on the old side"`
NewCount int `json:"newCount,omitempty"`
Fields []ACLFieldDelta `json:"fields,omitempty" jsonschema:"what a changed entry gained and lost, field by field"`
Note string `` /* 140-byte string literal not displayed */
OldPointer string `json:"oldPointer,omitempty" tk:"untrusted,emails" jsonschema:"JSON pointer into the old side"`
NewPointer string `json:"newPointer,omitempty" tk:"untrusted,emails" jsonschema:"JSON pointer into the new side"`
OldLine int `json:"oldLine,omitempty" jsonschema:"in the old side's text, from 1"`
NewLine int `` /* 131-byte string literal not displayed */
}
ACLChange is one difference. Entry, Old and New are cut at 1 KiB each by the engine, so that one element is never a blob and a page is bounded.
type ACLChangeCounts ¶ added in v0.6.0
type ACLChangeCounts struct {
Defaults int `json:"defaults"`
TestsReduced int `json:"testsReduced"`
Widening int `json:"widening"`
TailscaleWritten int `json:"tailscaleWritten"`
Semantic int `json:"semantic"`
CommentOnly int `json:"commentOnly"`
FormatOnly int `json:"formatOnly"`
}
ACLChangeCounts are the differences between the validated text and the live policy, by class.
type ACLDiffInput ¶ added in v0.6.0
type ACLDiffInput struct {
Policy string `` /* 192-byte string literal not displayed */
Patch string `` /* 210-byte string literal not displayed */
Against string `` /* 161-byte string literal not displayed */
FromVersion string `json:"fromVersion,omitempty" tk:"short" jsonschema:"the old side is the policy of this version id from acl_history"`
ToVersion string `json:"toVersion,omitempty" tk:"short" jsonschema:"the new side is the policy of this version id from acl_history"`
Section string `` /* 169-byte string literal not displayed */
FromChange string `` /* 135-byte string literal not displayed */
IgnoreTailscaleWritten bool `` /* 154-byte string literal not displayed */
Offline bool `` /* 131-byte string literal not displayed */
Operator bool `json:"-" cli:"operator"`
}
ACLDiffInput says which two policies to compare, and which changes to list.
func (ACLDiffInput) Check ¶ added in v0.6.0
func (in ACLDiffInput) Check() error
Check refuses a policy and a patch together, a version and a text for the same side, and a section that is no section, before anything is read. That both sides are the live policy is told by the tool, since on the command line the files are not read yet.
func (ACLDiffInput) RunsOffline ¶ added in v0.6.0
func (in ACLDiffInput) RunsOffline(g registry.Given) bool
RunsOffline says that two files, or --offline, need no credential. --offline with a live side is refused by the tool, which says so.
type ACLDiffOutput ¶ added in v0.6.0
type ACLDiffOutput struct {
Status string `json:"status" jsonschema:"equal, changed or invalid (a side is not a policy, and nothing was compared)"`
SemanticallyEqual bool `` /* 175-byte string literal not displayed */
Old ACLDiffSide `json:"old"`
New ACLDiffSide `json:"new"`
Counts ACLChangeCounts `json:"counts" jsonschema:"the changes of every page, by class; commentOnly and formatOnly are counts only"`
Changes []ACLChange `json:"changes,omitempty" jsonschema:"one page of the changes, defaults, testsReduced and widening first"`
Section string `` /* 172-byte string literal not displayed */
Matched int `json:"matched" jsonschema:"the changes the section filter and the options select, over every page"`
Truncated bool `json:"truncated" jsonschema:"more changes follow this page: call again with fromChange set to nextChange"`
NextChange string `json:"nextChange,omitempty"`
NormalFormLimits []string `json:"normalFormLimits,omitempty" jsonschema:"why a changed may be false"`
NotChecked []string `json:"notChecked" jsonschema:"what a comparison does not establish: a small change to an alias or a group can widen access"`
TailscaleWrittenAsOf string `json:"tailscaleWrittenAsOf" jsonschema:"the date of the list of constructs Tailscale writes itself"`
TailscaleWrittenIgnored bool `` /* 148-byte string literal not displayed */
ExternallyManaged string `` /* 153-byte string literal not displayed */
ExternalLink string `json:"externalLink,omitempty" tk:"untrusted,plain"`
ExternallyManagedNote string `json:"externallyManagedNote,omitempty" jsonschema:"why it is unknown"`
CheckedAt string `json:"checkedAt"`
}
ACLDiffOutput is the comparison. An invalid side is a typed result too (status invalid, exit 2) with its findings under the side, so that a hostile name is redacted by the registry and not withheld with the rest.
func (ACLDiffOutput) ExitCode ¶ added in v0.6.0
func (o ACLDiffOutput) ExitCode() int
ExitCode comes from the status alone: equal and changed 0, invalid 2, and a status this version does not know 1. The status is the engine's verdict on the whole normal forms, never a reading of the page or of the filter: a section that selects nothing, or a cursor past the last change, leaves the status changed.
func (ACLDiffOutput) FailOnKinds ¶ added in v0.6.0
func (ACLDiffOutput) FailOnKinds() []string
FailOnKinds: acl_diff computes four kinds; it has no warnings to count.
func (ACLDiffOutput) Findings ¶ added in v0.6.0
func (o ACLDiffOutput) Findings() registry.Findings
Findings counts what --fail-on can gate, over every change and not the page. The kind change fires for any of the five classes: a gate named change that stays silent for a widening or a removed test is the unsafe direction. The Tailscale-written class counts unless the caller asked to ignore it.
func (ACLDiffOutput) Report ¶ added in v0.6.0
func (o ACLDiffOutput) Report() registry.Report
Report is the human layout: the verdict line, what was not checked, the counts by class, then the findings of each side and the changes of the page, each behind a location. The strings are the registry's, already escaped and masked; a line that quotes a policy is the owner's own text and is not marked as Tailscale's.
type ACLDiffSide ¶ added in v0.6.0
type ACLDiffSide struct {
Source string `` /* 174-byte string literal not displayed */
Version string `json:"version,omitempty" jsonschema:"the version id, when source is version"`
PolicyVersion string `` /* 145-byte string literal not displayed */
PolicySHA256 string `json:"policySha256,omitempty" jsonschema:"SHA-256 of the policy as acl_get shows it"`
Findings []ACLProblem `` /* 164-byte string literal not displayed */
Omitted int `json:"omitted,omitempty" jsonschema:"findings left out past the cap"`
}
ACLDiffSide describes one side of the comparison.
type ACLFieldDelta ¶ added in v0.6.0
type ACLFieldDelta struct {
Field string `json:"field" tk:"untrusted,emails"`
Added []string `json:"added,omitempty" tk:"untrusted,emails"`
Removed []string `json:"removed,omitempty" tk:"untrusted,emails"`
AddedMore int `json:"addedMore,omitempty" jsonschema:"gained, not listed"`
RemovedMore int `json:"removedMore,omitempty" jsonschema:"lost, not listed"`
}
ACLFieldDelta is what a changed entry gained and lost in one field.
type ACLGetInput ¶
type ACLGetInput struct {
FromLine int `json:"fromLine,omitempty" jsonschema:"first line of the page, from 1 (default 1); use nextLine from the previous page"`
MaxBytes int `` /* 212-byte string literal not displayed */
View string `` /* 155-byte string literal not displayed */
}
ACLGetInput selects a page of the policy, or the summary.
func (ACLGetInput) Check ¶ added in v0.6.0
func (in ACLGetInput) Check() error
Check refuses a page that cannot exist, before anything is sent. Zero means the default.
type ACLGetOutput ¶
type ACLGetOutput struct {
Policy string `` /* 255-byte string literal not displayed */
FromLine int `json:"fromLine" jsonschema:"first line of this page; 0 in the summary"`
ToLine int `json:"toLine" jsonschema:"last line of this page; 0 in the summary"`
Lines int `json:"lines" jsonschema:"lines in the whole policy"`
NextLine int `json:"nextLine" jsonschema:"fromLine of the next page; 0 on the last page"`
Truncated bool `json:"truncated" jsonschema:"more lines follow this page"`
Masked bool `json:"masked" jsonschema:"email addresses on this page were masked (in the summary: anywhere in the policy)"`
Bytes int `` /* 176-byte string literal not displayed */
SHA256 string `json:"sha256" jsonschema:"SHA-256 of the whole policy, of the same bytes as bytes"`
ETag string `` /* 147-byte string literal not displayed */
PolicyVersion string `` /* 153-byte string literal not displayed */
PolicySHA256 string `json:"policySha256" jsonschema:"the same value as sha256"`
CheckedAt string `json:"checkedAt" jsonschema:"when the policy was read: RFC 3339, in UTC"`
Warnings []string `` /* 160-byte string literal not displayed */
ServerErrors []string `` /* 166-byte string literal not displayed */
Summary *ACLSummary `json:"summary,omitempty" tk:"details" jsonschema:"the policy at a glance; view summary only"`
ExternallyManaged string `` /* 140-byte string literal not displayed */
ExternalLink string `json:"externalLink,omitempty" tk:"untrusted,plain"`
ExternallyManagedNote string `json:"externallyManagedNote,omitempty" jsonschema:"why externallyManaged is unknown"`
}
ACLGetOutput is a page of the policy, or its summary, and facts about the whole file.
func (ACLGetOutput) Block ¶
func (o ACLGetOutput) Block() (int, string)
Block lets the CLI print the page as a document: these fields first, then the policy lines with their numbers.
func (ACLGetOutput) Details ¶ added in v0.6.0
func (o ACLGetOutput) Details() []string
Details lets the CLI print the warnings, the stored errors and the summary one to a line, each behind a notice that the text is not tailkeeper's.
type ACLHistoryInput ¶ added in v0.6.0
type ACLHistoryInput struct {
Start string `` /* 126-byte string literal not displayed */
End string `json:"end,omitempty" tk:"short" jsonschema:"RFC 3339 end (default now)"`
Limit int `json:"limit,omitempty" jsonschema:"page size, 1-200 (default 50)"`
Cursor string `json:"cursor,omitempty" tk:"short" jsonschema:"nextCursor of the previous page; it fixes the window, so omit start and end"`
}
ACLHistoryInput selects policy versions from the configuration audit log. The log has no pagination: tailkeeper reads the window in slices and pages over what came back.
func (ACLHistoryInput) Check ¶ added in v0.6.0
func (in ACLHistoryInput) Check() error
Check refuses a limit out of range, a cursor given with a window or that no page issued, and a window longer than 90 days, before anything is sent.
type ACLHistoryOutput ¶ added in v0.6.0
type ACLHistoryOutput struct {
Versions []ACLVersion `json:"versions" tk:"rows"`
Count int `json:"count"`
WindowStart string `json:"windowStart"`
WindowEnd string `json:"windowEnd"`
NextCursor string `json:"nextCursor,omitempty"`
Skipped int `json:"skipped,omitempty"`
Note string `json:"note"`
}
ACLHistoryOutput is one page of policy versions, oldest first.
type ACLProblem ¶ added in v0.6.0
type ACLProblem struct {
Kind string `json:"kind" jsonschema:"the kind of finding, as the tool's description lists"`
Severity string `json:"severity" jsonschema:"error, warning or notice"`
Source string `` /* 193-byte string literal not displayed */
Line int `json:"line,omitempty" jsonschema:"from 1, counting line feeds as Tailscale does; absent when unknown"`
Column int `json:"column,omitempty" jsonschema:"in bytes, from 1"`
Pointer string `json:"pointer,omitempty" tk:"untrusted,emails" jsonschema:"JSON pointer, when the line is not known"`
Message string `json:"message" tk:"untrusted,emails"`
FromTailscale bool `json:"fromTailscale" jsonschema:"Tailscale's own text"`
MoreCandidates int `json:"moreCandidates,omitempty" jsonschema:"more places match, past the cap"`
}
ACLProblem is one thing a validation found, placed in the text it is about. Line and Column are counted as Tailscale counts them: lines by line feed, columns in bytes.
type ACLSSHTestInput ¶ added in v0.6.0
type ACLSSHTestInput struct {
Dst []string `json:"dst" jsonschema:"destinations of this SSH test, with no port (tag:prod, 100.64.0.5)"`
Accept []string `json:"accept,omitempty" jsonschema:"SSH users that must be accepted"`
Check []string `json:"check,omitempty" jsonschema:"SSH users that must be checked"`
Deny []string `json:"deny,omitempty" jsonschema:"SSH users that must be denied"`
}
ACLSSHTestInput is one SSH test: destinations and the users that must be accepted, checked or denied. The source is the call's src, not a field of this struct.
type ACLSSHVerdict ¶ added in v0.6.0
type ACLSSHVerdict struct {
Dst string `json:"dst" tk:"untrusted,emails" jsonschema:"the destination as the caller wrote it"`
User string `json:"user" tk:"untrusted,emails" jsonschema:"the SSH user as the caller wrote it"`
Expect string `json:"expect" jsonschema:"accept, check or deny"`
Verdict string `json:"verdict" jsonschema:"allowed, denied, unresolved or unknown"`
Why string `json:"why,omitempty" jsonschema:"a fixed sentence, when the line alone is not the whole reason"`
}
ACLSSHVerdict is what the reply says about one SSH user on one destination, as the caller wrote them. Expect is accept, check or deny. Verdict is allowed, denied, unresolved or unknown. Why, when set, is one of sshVerdictReasons.
type ACLSectionRow ¶ added in v0.6.0
type ACLSectionRow struct {
Name string `json:"name" tk:"untrusted,emails" jsonschema:"section name"`
Known bool `json:"known" jsonschema:"this version knows the section"`
State string `json:"state" jsonschema:"absent, empty or non-empty"`
Count int `json:"count" jsonschema:"elements or entries; 1 for a value"`
Scalar string `json:"scalar,omitempty" tk:"untrusted,emails" jsonschema:"the value of a scalar section"`
}
ACLSectionRow is one section of a policy at a glance.
type ACLSummary ¶ added in v0.6.0
type ACLSummary struct {
Sections []ACLSectionRow `json:"sections" jsonschema:"every section: those this version knows in table order, then the others by name"`
Groups []string `json:"groups,omitempty" tk:"untrusted,emails" jsonschema:"names defined in groups, sorted"`
TagOwners []string `json:"tagOwners,omitempty" tk:"untrusted,emails" jsonschema:"tags in tagOwners, sorted"`
Hosts []string `json:"hosts,omitempty" tk:"untrusted,emails" jsonschema:"host aliases, sorted"`
Postures []string `json:"postures,omitempty" tk:"untrusted,emails" jsonschema:"posture names, sorted"`
IPSets []string `json:"ipsets,omitempty" tk:"untrusted,emails" jsonschema:"ipset names, sorted"`
SyncedGroups []string `` /* 153-byte string literal not displayed */
NamesTruncated bool `json:"namesTruncated" jsonschema:"a list was cut: at 100 names, or to fit the result"`
Tests int `json:"tests" jsonschema:"elements of tests"`
SSHTests int `json:"sshTests" jsonschema:"elements of sshTests"`
Unknown []string `json:"unknown,omitempty" tk:"untrusted,emails" jsonschema:"sections this version does not know"`
NamesDigest string `json:"namesDigest,omitempty" jsonschema:"keyed digest of the names; needs a privacy key"`
SemanticDigest string `` /* 156-byte string literal not displayed */
}
ACLSummary is a policy at a glance: what it holds and what it defines, without its rules.
type ACLTestInput ¶
type ACLTestInput struct {
Src string `` /* 170-byte string literal not displayed */
Accept []string `` /* 132-byte string literal not displayed */
Deny []string `json:"deny,omitempty" jsonschema:"destinations src must not reach, as host:port"`
Proto string `` /* 190-byte string literal not displayed */
SrcPostureAttrs map[string]any `` /* 300-byte string literal not displayed */
SSH []ACLSSHTestInput `` /* 175-byte string literal not displayed */
}
ACLTestInput is one test: a source and the destinations it must or must not reach.
func (ACLTestInput) Check ¶ added in v0.6.0
func (in ACLTestInput) Check() error
Check refuses a test that is malformed or has nothing to test, before anything is sent.
type ACLTestOutput ¶
type ACLTestOutput struct {
Status string `` /* 195-byte string literal not displayed */
Verdicts []ACLTestVerdict `json:"verdicts,omitempty"`
SSHVerdicts []ACLSSHVerdict `json:"sshVerdicts,omitempty"`
Omitted int `` /* 140-byte string literal not displayed */
SSHNotAsked int `` /* 130-byte string literal not displayed */
SSHError string `` /* 199-byte string literal not displayed */
OmittedLines int `` /* 174-byte string literal not displayed */
Failures []ACLTestResult `json:"failures,omitempty" tk:"details"`
Unmatched []string `json:"unmatched,omitempty" tk:"untrusted,emails,details"`
OtherTests []ACLTestResult `json:"otherTests,omitempty" tk:"details"`
Warnings []string `json:"warnings,omitempty" tk:"untrusted,emails,details"`
Posture string `` /* 141-byte string literal not displayed */
PosturesNeeded []string `json:"posturesNeeded,omitempty" tk:"untrusted,emails" jsonschema:"the posture attributes the live policy names"`
PostureNote string `` /* 141-byte string literal not displayed */
Caveats []string `json:"caveats,omitempty" jsonschema:"fixed sentences about how a verdict was read"`
EvaluatedAt string `json:"evaluatedAt"`
Note string `json:"note"`
}
ACLTestOutput is the live policy's answer for the posted source.
func (ACLTestOutput) ExitCode ¶
func (o ACLTestOutput) ExitCode() int
ExitCode is 0 for a pass, 1 for unknown or a status this version does not know, 2 for unresolved and 9 for a failed assertion.
func (ACLTestOutput) Report ¶ added in v0.6.0
func (o ACLTestOutput) Report() registry.Report
Report is the human layout: one verdict line, the facts the result states under their labels, what it did not check, then Tailscale's lines behind the notice the layout prints for untrusted findings.
type ACLTestResult ¶
type ACLTestResult struct {
Src string `json:"src" tk:"untrusted,emails"`
Errors []string `json:"errors" tk:"untrusted,emails"`
}
ACLTestResult is Tailscale's reasons for one source.
type ACLTestVerdict ¶ added in v0.6.0
type ACLTestVerdict struct {
Dst string `json:"dst" tk:"untrusted,emails" jsonschema:"the destination as the caller wrote it"`
Expect string `json:"expect" jsonschema:"accept, deny or accept+deny"`
Verdict string `json:"verdict" jsonschema:"allowed, denied, unresolved or unknown"`
Why string `json:"why,omitempty" jsonschema:"a fixed sentence, when the line alone is not the whole reason"`
Protocols []string `json:"protocols,omitempty" tk:"untrusted" jsonschema:"the protocol names of the lines that speak for this destination"`
}
ACLTestVerdict is what the reply says about one destination, as the caller wrote it.
type ACLValidateInput ¶ added in v0.6.0
type ACLValidateInput struct {
Policy string `` /* 180-byte string literal not displayed */
Patch string `` /* 194-byte string literal not displayed */
Invariants string `` /* 178-byte string literal not displayed */
NoInvariants bool `json:"-" cli:"bool:no-invariants" jsonschema:"do not check the configured invariants"`
Offline bool `` /* 206-byte string literal not displayed */
Operator bool `json:"-" cli:"operator"`
}
ACLValidateInput is a proposal to validate.
func (ACLValidateInput) Check ¶ added in v0.6.0
func (in ACLValidateInput) Check() error
Check refuses a policy and a patch together, before anything is sent: the policy is the whole proposal, and the patch is a change to the live policy. On the command line the two flags are one group, and the binder refuses both before this runs.
func (ACLValidateInput) RunsOffline ¶ added in v0.6.0
func (in ACLValidateInput) RunsOffline(g registry.Given) bool
RunsOffline says that --offline needs no credential.
type ACLValidateOutput ¶ added in v0.6.0
type ACLValidateOutput struct {
Status string `` /* 248-byte string literal not displayed */
ServerChecked bool `json:"serverChecked" jsonschema:"false: the text was not sent to Tailscale, so a pass is a local one"`
Errors []ACLProblem `json:"errors,omitempty" jsonschema:"what made the status what it is, placed in the text where possible"`
Notices []ACLProblem `json:"notices,omitempty" jsonschema:"remarks that change no status"`
// NewWarnings are the warnings the text adds to the live policy's own; ExistingWarnings
// are the ones the live policy already has. A warning is existing only when it matches one
// stored with the live policy word for word (see warnings in acl_validate_online.go), so
// the doubt falls on the side of a gate: a warning worded differently reads as new.
NewWarnings []ACLProblem `` /* 208-byte string literal not displayed */
ExistingWarnings []ACLProblem `json:"existingWarnings,omitempty" jsonschema:"warnings the live policy already has"`
// NewWarningsOmitted counts the new warnings that NewWarnings does not list, past the caps
// on what a reply and a result carry; they are part of Omitted, and --fail-on warnings
// counts them.
NewWarningsOmitted int `` /* 143-byte string literal not displayed */
ServerErrors []string `json:"serverErrors,omitempty" tk:"untrusted,emails" jsonschema:"errors stored with the live policy"`
Omitted int `json:"omitted,omitempty" jsonschema:"problems left out past the caps"`
TestsBefore int `json:"testsBefore" jsonschema:"in the live policy; 0 when not read"`
TestsAfter int `json:"testsAfter" jsonschema:"in the validated text"`
SSHTestsBefore int `json:"sshTestsBefore"`
SSHTestsAfter int `json:"sshTestsAfter"`
// Changes counts the differences from the live policy by class.
Changes *ACLChangeCounts `json:"changes,omitempty" jsonschema:"differences from the live policy, by class"`
InvariantsApplied int `json:"invariantsApplied" jsonschema:"invariant tests that ran; 0 means none"`
InvariantsSignature string `json:"invariantsSignature" jsonschema:"always none: unsigned"`
NotChecked []string `json:"notChecked" jsonschema:"what this does not establish"`
DependsOnLiveState bool `json:"dependsOnLiveState" jsonschema:"the answer depends on the live policy"`
PolicyVersion string `` /* 145-byte string literal not displayed */
PolicySHA256 string `json:"policySha256,omitempty" jsonschema:"SHA-256 of the live policy as acl_get shows it"`
LiveChanged bool `json:"liveChanged" jsonschema:"the live policy changed during the check; never a pass"`
ValidatedLive bool `` /* 162-byte string literal not displayed */
IdenticalToLive bool `json:"identicalToLive" jsonschema:"the text is byte for byte the live policy"`
CheckedAt string `json:"checkedAt"`
ExternallyManaged string `json:"externallyManaged" jsonschema:"true, false or unknown: managed outside the admin console"`
ExternalLink string `json:"externalLink,omitempty" tk:"untrusted,plain"`
ExternallyManagedNote string `json:"externallyManagedNote,omitempty" jsonschema:"why it is unknown"`
PatchedBytes int `` /* 153-byte string literal not displayed */
PatchedDigest string `` /* 151-byte string literal not displayed */
// contains filtered or unexported fields
}
ACLValidateOutput is the verdict on a proposal. Every verdict is a typed result, the invalid and rejected ones too, so that the registry redacts a hostile name instead of withholding the whole result; the exit code comes from Status alone.
func (ACLValidateOutput) ExitCode ¶ added in v0.6.0
func (o ACLValidateOutput) ExitCode() int
ExitCode comes from the verdict alone, never from message text: pass 0, unknown 1, invalid, rejected and unresolved 2, fail 9. A status this version does not know is unknown.
func (ACLValidateOutput) FailOnKinds ¶ added in v0.6.0
func (ACLValidateOutput) FailOnKinds() []string
FailOnKinds: acl_validate computes all five kinds.
func (ACLValidateOutput) Findings ¶ added in v0.6.0
func (o ACLValidateOutput) Findings() registry.Findings
Findings counts what --fail-on can gate. Every kind is computed over all the changes, not over a page of them. The kind change fires for any of the five classes, the Tailscale-written ones included, because a gate named change that stays silent for a widening is the unsafe direction.
func (ACLValidateOutput) OfflineFailOnKinds ¶ added in v0.6.0
func (ACLValidateOutput) OfflineFailOnKinds() []string
OfflineFailOnKinds: an offline check compares nothing with the live policy and sends nothing, so it computes none of the five kinds, and --fail-on is refused with --offline.
func (ACLValidateOutput) Report ¶ added in v0.6.0
func (o ACLValidateOutput) Report() registry.Report
Report is the human layout: the verdict line, what was not checked, the diff counts by class, then the problems, each behind a location. Tailscale's own words are marked untrusted so that the layout prints them behind a notice.
type ACLVersion ¶ added in v0.6.0
type ACLVersion struct {
Version string `json:"version" tk:"col"`
Previous string `json:"previous,omitempty" tk:"col"`
EventTime string `json:"eventTime" tk:"col"`
Origin string `json:"origin" tk:"col,untrusted"`
Actor AuditActor `json:"actor"`
Bytes int `json:"bytes" tk:"col"`
Digest string `json:"digest,omitempty"`
PolicyVersion string `json:"policyVersion,omitempty"`
PolicySHA256 string `json:"policySha256"`
}
ACLVersion is one policy the log recorded. The text itself is not here: a version id is how acl_diff asks for it. policyVersion and policySha256 describe the text as acl_get would show it, so neither is a hash of a login.
type Acceptor ¶
type Acceptor struct {
ID int64 `json:"id"`
LoginName string `json:"loginName" tk:"untrusted,personal"`
}
Acceptor is who accepted an invite.
type AuditActor ¶
type AuditActor struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
LoginName string `json:"loginName,omitempty" tk:"untrusted,personal"`
DisplayName string `json:"displayName,omitempty" tk:"untrusted,personal"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
}
AuditActor is who made a change.
type AuditEntry ¶
type AuditEntry struct {
EventTime string `json:"eventTime" tk:"col"`
DeferredAt string `json:"deferredAt,omitempty"`
EventGroupID string `json:"eventGroupId,omitempty"`
Origin string `json:"origin" tk:"col"`
Action string `json:"action" tk:"col"`
Actor AuditActor `json:"actor"`
Target AuditTarget `json:"target"`
OldDigest string `` /* 214-byte string literal not displayed */
NewDigest string `json:"newDigest,omitempty" jsonschema:"as oldDigest"`
OldPreview string `json:"oldPreview,omitempty" tk:"untrusted,premasked"`
NewPreview string `json:"newPreview,omitempty" tk:"untrusted,premasked"`
ActionDetails string `json:"actionDetails,omitempty" tk:"untrusted"`
Error string `json:"error,omitempty" tk:"untrusted"`
}
AuditEntry is one configuration audit-log entry. old/new can hold whole policy files and personal data, so they are returned as a digest and, only on request (includeValues), a short untrusted preview.
type AuditLogInput ¶
type AuditLogInput struct {
Start string `json:"start,omitempty" jsonschema:"RFC 3339 start (default end minus 24h)"`
End string `json:"end,omitempty" jsonschema:"RFC 3339 end (default now); the window may span at most 31 days"`
Actor []string `` /* 273-byte string literal not displayed */
Target []string `` /* 457-byte string literal not displayed */
Event []string `json:"event,omitempty" jsonschema:"event names such as TAILNET.UPDATE.ACL (server-side)"`
Origin []string `json:"origin,omitempty" jsonschema:"origins such as ADMIN_CONSOLE or CONFIG_API (client-side)"`
IncludeValues bool `` /* 474-byte string literal not displayed */
Limit int `json:"limit,omitempty" jsonschema:"page size, 1-5000 (default 500)"`
Cursor string `` /* 167-byte string literal not displayed */
}
AuditLogInput selects configuration audit-log entries. The API has no pagination: it returns the whole window, and tailkeeper pages over that response.
func (AuditLogInput) Check ¶ added in v0.6.0
func (in AuditLogInput) Check() error
Check refuses a limit out of range, a cursor given with a window or that no page issued, and a window that is malformed or too long, before anything is sent. What depends on the filters or the privacy setting waits for the run. Zero means the default limit.
type AuditLogOutput ¶
type AuditLogOutput struct {
Entries []AuditEntry `json:"entries" tk:"rows"`
Count int `json:"count"`
WindowStart string `json:"windowStart"`
WindowEnd string `json:"windowEnd"`
NextCursor string `json:"nextCursor,omitempty"`
Note string `json:"note"`
}
AuditLogOutput is one page of entries, oldest first.
type AuditTarget ¶
type AuditTarget struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty" tk:"untrusted"`
Type string `json:"type,omitempty"`
IsEphemeral bool `json:"isEphemeral,omitempty"`
Property string `json:"property,omitempty" tk:"untrusted"`
}
AuditTarget is what changed.
type AuthKeyCaps ¶
type AuthKeyCaps struct {
Reusable bool `json:"reusable"`
Ephemeral bool `json:"ephemeral"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
}
AuthKeyCaps are the capabilities of an auth key.
type Connectivity ¶
type Connectivity struct {
HardNAT bool `json:"hardNat" jsonschema:"mappingVariesByDestIP: the NAT maps differently per destination"`
Supports Supports `json:"supports"`
PreferredDERP string `json:"preferredDerp,omitempty" tk:"untrusted"`
PreferredLatencyMs float64 `json:"preferredLatencyMs,omitempty"`
}
Connectivity summarises clientConnectivity without public endpoints.
type Contact ¶
type Contact struct {
Email string `json:"email,omitempty" tk:"untrusted,personal"`
FallbackEmail string `json:"fallbackEmail,omitempty" tk:"untrusted,personal"`
NeedsVerification *bool `json:"needsVerification" jsonschema:"null when the API did not say; only an explicit false counts as verified"`
}
Contact is one tailnet contact.
type ContactsOutput ¶
type ContactsOutput struct {
Account *Contact `json:"account,omitempty"`
Support *Contact `json:"support,omitempty"`
Security *Contact `json:"security,omitempty"`
SecurityContactOK bool `` /* 134-byte string literal not displayed */
}
ContactsOutput lists the tailnet's contacts.
type DNSAnswer ¶
type DNSAnswer struct {
Name string `json:"name" tk:"untrusted,col"`
Type string `json:"type" tk:"col"`
TTL int `json:"ttl" tk:"col"`
Body string `json:"body" tk:"untrusted,col,plain"`
}
DNSAnswer is one answer record.
type DNSNodeAttr ¶ added in v0.6.0
type DNSNodeAttr struct {
Attr string `json:"attr"`
Targets []string `json:"targets" tk:"untrusted,emails"`
}
DNSNodeAttr is one of the seven DNS node attributes, with the selectors it applies to.
type DNSOutput ¶
type DNSOutput struct {
Nameservers []Resolver `json:"nameservers"`
SplitDNS []SplitDomain `json:"splitDns"`
SearchPaths []string `json:"searchPaths" tk:"untrusted"`
MagicDNS *bool `json:"magicDns" jsonschema:"null when the API did not say"`
OverrideLocalDNS *bool `json:"overrideLocalDns" jsonschema:"null when the API did not say"`
PolicyOverridesAnalysed bool `json:"policyOverridesAnalysed" jsonschema:"true when extraDNSRecords and DNS node attributes were read from the policy"`
PolicyNote string `json:"policyNote,omitempty" jsonschema:"why the policy part is missing or cut: a fixed sentence"`
ExtraRecords []ExtraDNSRecord `json:"extraDnsRecords,omitempty"`
ExtraRecordsEffectiveIf []string `json:"extraDnsRecordsEffectiveIf,omitempty" jsonschema:"settings the extra records need before they take effect"`
NextDNS []DNSResolverAttr `json:"nextdns,omitempty"`
ControlD []DNSResolverAttr `json:"controlD,omitempty"`
ResolverNote string `` /* 144-byte string literal not displayed */
DNSNodeAttrs []DNSNodeAttr `json:"dnsNodeAttrs,omitempty"`
OtherAttrs []string `json:"otherAttrs,omitempty" tk:"untrusted,emails"`
AttrTableAsOf string `json:"attrTableAsOf,omitempty" jsonschema:"the date of the table of DNS node attributes this tool knows"`
Truncated bool `json:"truncated,omitempty" jsonschema:"true when a list was cut at 100 entries or at the size limit"`
}
DNSOutput is the tailnet's DNS configuration from /dns/configuration, plus what the policy sets for DNS when the read credential may read the policy.
type DNSQueryInput ¶
type DNSQueryInput struct {
Name string `json:"name" jsonschema:"a name under the tailnet's MagicDNS suffix, or allowed by local.dnsQueryAllowlist"`
Type string `json:"type,omitempty" jsonschema:"A (default), AAAA, CNAME, MX, NS, PTR, SRV or TXT"`
}
DNSQueryInput is a name lookup.
type DNSQueryOutput ¶
type DNSQueryOutput struct {
Name string `json:"name" tk:"untrusted"`
Type string `json:"type"`
ResponseCode string `json:"responseCode"`
Resolvers []string `json:"resolvers" tk:"untrusted,plain"`
Answers []DNSAnswer `json:"answers" tk:"rows"`
}
DNSQueryOutput is the lookup result.
type DNSResolverAttr ¶ added in v0.6.0
type DNSResolverAttr struct {
Targets []string `json:"targets" tk:"untrusted,emails"`
ID string `json:"id" tk:"untrusted,personal"`
Priority *int `json:"priority,omitempty"`
NoDeviceInfo bool `json:"noDeviceInfo,omitempty"`
}
DNSResolverAttr is one NextDNS or Control D attribute. Targets are selectors. ID is the profile identifier, masked whole.
type Device ¶
type Device struct {
NodeID string `json:"nodeId" tk:"col"`
Name string `json:"name" tk:"untrusted,col"`
Hostname string `json:"hostname" tk:"untrusted"`
User string `json:"user" tk:"untrusted,col,personal"`
OS string `json:"os" tk:"untrusted,col"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
Addresses []string `json:"addresses,omitempty"`
ClientVersion string `json:"clientVersion,omitempty" tk:"untrusted"`
UpdateAvailable bool `json:"updateAvailable"`
Created string `json:"created,omitempty"`
Expires string `json:"expires,omitempty"`
LastSeen string `json:"lastSeen,omitempty" tk:"col"`
ConnectedToControl bool `json:"connectedToControl" tk:"col"`
KeyExpiryDisabled bool `json:"keyExpiryDisabled"`
Authorized bool `json:"authorized"`
IsExternal bool `json:"isExternal"`
IsEphemeral bool `json:"isEphemeral"`
BlocksIncomingConnections bool `json:"blocksIncomingConnections"`
TailnetLockError string `json:"tailnetLockError,omitempty" tk:"untrusted"`
MultipleConnections *bool `json:"multipleConnections,omitempty"`
SSHEnabled *bool `json:"sshEnabled,omitempty"`
AdvertisedRoutes []string `json:"advertisedRoutes,omitempty" tk:"untrusted,plain"`
EnabledRoutes []string `json:"enabledRoutes,omitempty" tk:"untrusted,plain"`
Connectivity *Connectivity `json:"connectivity,omitempty"`
Distro *Distro `json:"distro,omitempty" tk:"untrusted"`
Fields string `json:"fields" jsonschema:"default or all: which API field set was requested; fields absent here are unknown, not false"`
}
Device is the device shape tailkeeper returns.
type DeviceInvite ¶
type DeviceInvite struct {
ID string `json:"id" tk:"col"`
Created string `json:"created,omitempty"`
DeviceID int64 `json:"deviceId,omitempty"`
MultiUse bool `json:"multiUse" tk:"col"`
AllowExitNode bool `json:"allowExitNode" tk:"col"`
Email string `json:"email,omitempty" tk:"untrusted,col,personal"`
LastEmailSentAt string `json:"lastEmailSentAt,omitempty"`
Accepted bool `json:"accepted" tk:"col"`
AcceptedBy *Acceptor `json:"acceptedBy,omitempty"`
}
DeviceInvite is a device-share invite. inviteUrl is a bearer link and is never returned (spec §7.6).
type DeviceInvitesOutput ¶
type DeviceInvitesOutput struct {
NodeID string `json:"nodeId"`
Invites []DeviceInvite `json:"invites" tk:"rows"`
Count int `json:"count"`
}
DeviceInvitesOutput lists a device's invites.
type DevicePostureOutput ¶
type DevicePostureOutput struct {
NodeID string `json:"nodeId"`
Attributes []PostureAttribute `json:"attributes" tk:"rows"`
}
DevicePostureOutput lists a device's posture attributes.
type DeviceRef ¶
type DeviceRef struct {
Device string `` /* 195-byte string literal not displayed */
}
DeviceRef names one device.
type DeviceRoutesInput ¶
type DeviceRoutesInput struct {
Device string `` /* 195-byte string literal not displayed */
IncludeHA bool `` /* 130-byte string literal not displayed */
}
DeviceRoutesInput selects a device and optionally computes HA peers.
func (DeviceRoutesInput) Check ¶ added in v0.6.0
func (in DeviceRoutesInput) Check() error
Check refuses a device reference that cannot name a device, before anything is sent.
type DeviceRoutesOutput ¶
type DeviceRoutesOutput struct {
NodeID string `json:"nodeId"`
Advertised []string `json:"advertised" tk:"untrusted,plain"`
Enabled []string `json:"enabled" tk:"untrusted,plain"`
Pending []string `json:"pending" jsonschema:"advertised but not approved" tk:"untrusted,plain"`
Latent []string `json:"latent" jsonschema:"approved but not advertised: activates if this identity ever advertises it" tk:"untrusted,plain"`
ExitNodeAdvertised bool `json:"exitNodeAdvertised"`
ExitNodeEnabled bool `json:"exitNodeEnabled"`
HAPeers []RoutePeer `json:"haPeers,omitempty"`
}
DeviceRoutesOutput shows route approval state.
type DevicesListInput ¶
type DevicesListInput struct {
Tags []string `json:"tags,omitempty" jsonschema:"devices must carry all of these tags (server-side, exact)"`
OS string `json:"os,omitempty" jsonschema:"exact OS name, for example linux, macOS, windows (server-side)"`
Hostname string `` /* 162-byte string literal not displayed */
User string `` /* 213-byte string literal not displayed */
Ephemeral *bool `json:"ephemeral,omitempty" jsonschema:"filter on isEphemeral (server-side)"`
Authorized *bool `json:"authorized,omitempty" jsonschema:"filter on authorized (server-side)"`
Online *bool `json:"online,omitempty" jsonschema:"filter on connectedToControl (server-side)"`
NameContains string `` /* 202-byte string literal not displayed */
StaleDays int `json:"staleDays,omitempty" jsonschema:"only devices not connected and last seen more than this many days ago (client-side)"`
AllFields bool `json:"allFields,omitempty" jsonschema:"request fields=all: routes, connectivity, SSH, cloned-state flag"`
}
DevicesListInput filters devices. Server-side filters are exact matches.
func (DevicesListInput) Check ¶ added in v0.6.0
func (in DevicesListInput) Check() error
Check refuses a staleDays or a tag that cannot be right, before anything is sent.
type DevicesListOutput ¶
type DevicesListOutput struct {
Devices []Device `json:"devices" tk:"rows"`
Count int `json:"count"`
Fields string `json:"fields"`
ServerFilters []string `json:"serverFilters"`
ClientFilters []string `json:"clientFilters"`
}
DevicesListOutput lists devices.
type Distro ¶
type Distro struct {
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
CodeName string `json:"codeName,omitempty"`
}
Distro is the reported OS distribution.
type ExtraDNSRecord ¶ added in v0.6.0
type ExtraDNSRecord struct {
Name string `json:"name" tk:"untrusted,emails"`
Type string `json:"type,omitempty" tk:"untrusted"`
Value string `json:"value" tk:"untrusted,emails" jsonschema:"email addresses in it are masked"`
}
ExtraDNSRecord is one extraDNSRecords entry. An empty Type means A or AAAA by the value.
type FailureKind ¶ added in v0.6.0
type FailureKind string
FailureKind says what a line of a validate reply is about a test.
const ( // AssertionFailed: a line in the want/got grammar, the server's answer that a // destination was accepted or dropped against the test's expectation. AssertionFailed FailureKind = "assertion_failed" // TestUnevaluable: anything else the server says about a test (a name it cannot resolve, // a destination kind tests do not take, a malformed test). It says nothing about access, // and is never read as a verdict. TestUnevaluable FailureKind = "test_unevaluable" )
type FailureLine ¶ added in v0.6.0
type FailureLine struct {
Kind FailureKind
SSH bool
Dst string // the address as the server quoted it (tests form), or the dst (SSH form)
User string // the ssh user the server quoted (SSH form); "" otherwise
Protocol string // "" when the line has none
Want string // "Accept" or "Drop" (tests), "accept" or "deny" (SSH)
Got string
}
FailureLine is one error line of a validate reply, read by the grammar of probe A-9 (20 Oct 2026). The zero fields of a TestUnevaluable line mean nothing.
func ParseFailureLine ¶ added in v0.6.0
func ParseFailureLine(line string) FailureLine
ParseFailureLine reads one error line. The grammar is positional and anchored, never a search: a tag or a host name can embed a destination and the words want and got, so every quoted field is read as one Go-quoted string from its opening quote, and the text after it must be exactly what the grammar says, to the end of the line.
[acl test error]: address "<dst>"( (protocol "<p>"))?: want: (Accept|Drop), got: (Accept|Drop) [ssh test error]: src "<s>" at "<ip>", dst "<d>" at "<ip>", ssh user "<u>": want: "accept" got: "deny"
A line that is not in the grammar, or whose quoted field does not unquote, or whose two verdicts are the same, is TestUnevaluable: that can only turn a verdict into "unresolved", never into a pass.
type Flow ¶
type Flow struct {
Kind string `json:"kind" jsonschema:"virtual, subnet, exit or physical"`
Proto string `json:"proto" tk:"untrusted"`
Src string `json:"src" tk:"untrusted"`
Dst string `json:"dst" tk:"untrusted"`
TxPkts int64 `json:"txPkts"`
TxBytes int64 `json:"txBytes"`
RxPkts int64 `json:"rxPkts"`
RxBytes int64 `json:"rxBytes"`
}
Flow is one traffic counter in a flow-log record.
type FlowLogsInput ¶
type FlowLogsInput struct {
Start string `json:"start,omitempty" jsonschema:"RFC 3339 start (default end minus 15m)"`
End string `json:"end,omitempty" jsonschema:"RFC 3339 end (default now); the window may span at most 1h"`
Node string `json:"node,omitempty" jsonschema:"only records logged by this node ID (client-side)"`
MaxRecords int `json:"maxRecords,omitempty" jsonschema:"1-10000 (default 1000)"`
}
FlowLogsInput selects a short window of network flow logs.
func (FlowLogsInput) Check ¶ added in v0.6.0
func (in FlowLogsInput) Check() error
Check refuses a window that is malformed or too long and a maxRecords out of range, before anything is sent. Zero means the default.
type FlowLogsOutput ¶
type FlowLogsOutput struct {
Status string `json:"status" jsonschema:"ok, not_enabled (flow logging is off) or not_available (not on this plan)"`
LoggingEnabled string `` /* 131-byte string literal not displayed */
Records []FlowRecord `json:"records"`
Count int `json:"count"`
Truncated bool `json:"truncated"`
AsOf string `json:"asOf"`
MayBeIncomplete bool `json:"mayBeIncomplete"`
Note string `json:"note"`
}
FlowLogsOutput reports flow records or why there are none.
type FlowRecord ¶
type FlowRecord struct {
NodeID string `json:"nodeId"`
Logged string `json:"logged"`
Start string `json:"start" tk:"untrusted"`
End string `json:"end" tk:"untrusted"`
Flows []Flow `json:"flows"`
}
FlowRecord is one node's 5-second window.
type IDRef ¶
type IDRef struct {
ID string `json:"id" jsonschema:"object ID"`
}
IDRef names an object by ID.
type InviteRef ¶
type InviteRef struct {
ID string `json:"id" jsonschema:"invite ID"`
}
InviteRef names one invite.
type Key ¶
type Key struct {
ID string `json:"id" tk:"col"`
KeyType string `json:"keyType" tk:"col"`
Description string `json:"description,omitempty" tk:"untrusted,col"`
Created string `json:"created,omitempty"`
Updated string `json:"updated,omitempty"`
Expires string `json:"expires,omitempty" tk:"col"`
Revoked string `json:"revoked,omitempty"`
Invalid bool `json:"invalid" tk:"col"`
Scopes []string `json:"scopes,omitempty"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
AuthKeyCapabilities *AuthKeyCaps `json:"authKeyCapabilities,omitempty"`
UserID string `json:"userId,omitempty"`
Issuer string `json:"issuer,omitempty" tk:"untrusted"`
Subject string `json:"subject,omitempty" tk:"untrusted"`
Audience string `json:"audience,omitempty" tk:"untrusted"`
CustomClaimRules map[string]string `json:"customClaimRules,omitempty" tk:"untrusted"`
}
Key is a key's metadata. The key material itself is never returned.
type KeyRef ¶
type KeyRef struct {
ID string `json:"id" jsonschema:"key ID"`
}
KeyRef names one key.
type KeysListOutput ¶
type KeysListOutput struct {
Keys []Key `json:"keys" tk:"rows"`
Count int `json:"count"`
Coverage map[string]string `json:"coverage" jsonschema:"per key type: visible, not_visible or unknown"`
Complete *bool `json:"complete,omitempty" jsonschema:"true only when every key type was visible; absent when unknown"`
}
KeysListOutput lists keys with an honest statement of what could be seen.
type LocalDNSStatusOutput ¶
type LocalDNSStatusOutput struct {
TailscaleDNS bool `json:"tailscaleDns" jsonschema:"the node accepts the tailnet DNS configuration (--accept-dns)"`
MagicDNSEnabled bool `json:"magicDnsEnabled"`
MagicDNSSuffix string `json:"magicDnsSuffix,omitempty" tk:"untrusted"`
SelfDNSName string `json:"selfDnsName,omitempty" tk:"untrusted"`
Resolvers []string `json:"resolvers" tk:"untrusted,plain" jsonschema:"the tailnet's resolvers in preference order; empty means system defaults"`
SplitDNS []SplitDomain `json:"splitDns"`
SearchDomains []string `json:"searchDomains" tk:"untrusted"`
SystemNameservers []string `json:"systemNameservers" tk:"untrusted,plain"`
SystemDNSError string `json:"systemDnsError,omitempty" tk:"untrusted"`
}
LocalDNSStatusOutput is the node's DNS view.
type LocalIPInput ¶
type LocalIPInput struct {
Peer string `json:"peer,omitempty" jsonschema:"a peer's tailnet IP (default: this node)"`
Family string `json:"family,omitempty" jsonschema:"4, 6 or 1 (first address only); default all"`
}
LocalIPInput selects which addresses local_ip prints.
type LocalIPOutput ¶
type LocalIPOutput struct {
Addresses []string `json:"addresses"`
}
LocalIPOutput lists addresses.
type LocalIdentity ¶
type LocalIdentity struct {
NodeID string `json:"nodeId"`
Name string `json:"name" tk:"untrusted"`
Addresses []string `json:"addresses"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
MachineAuthorized bool `json:"machineAuthorized"`
LoginName string `json:"loginName,omitempty" tk:"untrusted,personal"`
DisplayName string `json:"displayName,omitempty" tk:"untrusted,personal"`
Capabilities []string `` /* 159-byte string literal not displayed */
}
LocalIdentity is a node and its user.
type LocalPeer ¶
type LocalPeer struct {
NodeID string `json:"nodeId" tk:"col"`
HostName string `json:"hostName" tk:"untrusted,col"`
DNSName string `json:"dnsName" tk:"untrusted"`
OS string `json:"os,omitempty" tk:"untrusted,col"`
TailscaleIPs []string `json:"tailscaleIps"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
Online bool `json:"online" tk:"col"`
Active bool `json:"active"`
Path string `json:"path,omitempty" tk:"col" jsonschema:"direct, peer-relay, derp or none (peers only)"`
Relay string `json:"relay,omitempty" tk:"untrusted" jsonschema:"home DERP region code"`
ExitNode bool `json:"exitNode"`
ExitNodeOption bool `json:"exitNodeOption"`
LastHandshake string `json:"lastHandshake,omitempty"`
KeyExpiry string `json:"keyExpiry,omitempty"`
}
LocalPeer is a node as the local daemon sees it.
type LocalStatusInput ¶
type LocalStatusInput struct {
Peers bool `json:"peers,omitempty" jsonschema:"include peers"`
Active bool `json:"active,omitempty" jsonschema:"include only peers with active sessions (implies peers)"`
}
LocalStatusInput selects what local_status includes.
type LocalStatusOutput ¶
type LocalStatusOutput struct {
BackendState string `json:"backendState"`
NeedsLogin bool `json:"needsLogin"`
Version string `json:"version" tk:"untrusted"`
Self *LocalPeer `json:"self,omitempty"`
Tailnet string `` /* 139-byte string literal not displayed */
MagicDNSSuffix string `json:"magicDnsSuffix,omitempty" tk:"untrusted"`
MagicDNSEnabled bool `json:"magicDnsEnabled"`
Health []string `json:"health" tk:"untrusted"`
Peers []LocalPeer `json:"peers,omitempty" tk:"rows"`
PeerCount int `json:"peerCount"`
PeerScope string `` /* 132-byte string literal not displayed */
}
LocalStatusOutput is this node's status.
type LockStatusOutput ¶
type LockStatusOutput struct {
Enabled bool `json:"enabled"`
PublicKey string `json:"publicKey,omitempty" jsonschema:"this node's Tailnet Lock public key" tk:"untrusted"`
NodeKey string `json:"nodeKey,omitempty" jsonschema:"this node's public node key" tk:"untrusted"`
NodeKeySigned *bool `json:"nodeKeySigned,omitempty" jsonschema:"absent when Tailnet Lock is off" tk:"absentok"`
TrustedKeyCount int `json:"trustedKeyCount"`
VisiblePeerCount int `json:"visiblePeerCount"`
LockedOutPeers int `json:"lockedOutPeers" jsonschema:"peers filtered out because their node key is not signed"`
}
LockStatusOutput is Tailnet Lock as this node sees it.
type LogStreamConfig ¶
type LogStreamConfig struct {
DestinationType string `json:"destinationType,omitempty"`
URL string `json:"url,omitempty" tk:"untrusted,plain" jsonschema:"scheme and host only"`
URLPathHash string `json:"urlPathSha256,omitempty" jsonschema:"SHA-256 of the URL's path and query, which can carry a collector token"`
User string `json:"user,omitempty" tk:"untrusted,personal"`
UploadPeriodMinutes int `json:"uploadPeriodMinutes,omitempty"`
CompressionFormat string `json:"compressionFormat,omitempty"`
S3Bucket string `json:"s3Bucket,omitempty" tk:"untrusted"`
S3Region string `json:"s3Region,omitempty" tk:"untrusted"`
S3KeyPrefix string `json:"s3KeyPrefix,omitempty" tk:"untrusted"`
S3AuthenticationType string `json:"s3AuthenticationType,omitempty"`
S3AccessKeyID string `json:"s3AccessKeyId,omitempty" tk:"untrusted"`
S3RoleARN string `json:"s3RoleArn,omitempty" tk:"untrusted"`
S3ExternalID string `json:"s3ExternalId,omitempty" tk:"untrusted"`
GCSBucket string `json:"gcsBucket,omitempty" tk:"untrusted"`
GCSKeyPrefix string `json:"gcsKeyPrefix,omitempty" tk:"untrusted"`
GCSScopes []string `json:"gcsScopes,omitempty" tk:"untrusted"`
}
LogStreamConfig is a destination without its secrets (token, S3 secret key and GCS credentials are never returned).
type LogStreamInput ¶
type LogStreamInput struct {
LogType string `json:"logType" jsonschema:"configuration or network"`
}
LogStreamInput names a log type.
func (LogStreamInput) Check ¶ added in v0.6.0
func (in LogStreamInput) Check() error
Check refuses a log type Tailscale does not have, before anything is sent.
type LogStreamOutput ¶
type LogStreamOutput struct {
LogType string `json:"logType"`
Status string `json:"status" jsonschema:"configured or not_configured"`
Configuration *LogStreamConfig `json:"configuration,omitempty"`
Health *LogStreamStatus `json:"health,omitempty"`
HealthError string `json:"healthError,omitempty" jsonschema:"error code when delivery health could not be read"`
Findings []string `json:"findings"`
}
LogStreamOutput describes one log stream.
type LogStreamStatus ¶
type LogStreamStatus struct {
LastActivity string `json:"lastActivity,omitempty"`
LastError string `json:"lastError,omitempty" tk:"untrusted"`
NumBytesSent int64 `json:"numBytesSent"`
NumEntriesSent int64 `json:"numEntriesSent"`
NumSpoofedEntries int64 `json:"numSpoofedEntries"`
NumTotalRequests int64 `json:"numTotalRequests"`
NumFailedRequests int64 `json:"numFailedRequests"`
RateFailedRequests float64 `json:"rateFailedRequests"`
}
LogStreamStatus is delivery health.
type Login ¶ added in v0.6.0
type Login struct {
// contains filtered or unexported fields
}
Login is the login name of one user, resolved from a pseudonym. It exists to be sent to Tailscale in a request and to go nowhere else while personal data is masked: it prints as [login] under every fmt verb, encodes as "[login]" in JSON and text, and keeps the name in a function, as privacy.Key keeps its bytes, so that fmt cannot reach it through a struct field. Reveal is the one way to read it; its call site is the line that builds the request, and a line that puts it anywhere else is the bug.
func (Login) Format ¶ added in v0.6.0
Format keeps the login out of every format verb: fmt calls it before any other way of printing, so even the numeric verbs print the placeholder.
func (Login) MarshalJSON ¶ added in v0.6.0
MarshalJSON encodes the placeholder.
func (Login) MarshalText ¶ added in v0.6.0
MarshalText encodes the placeholder.
type Metric ¶
type Metric struct {
Name string `json:"name" tk:"col"`
Labels map[string]string `json:"labels,omitempty" tk:"untrusted"`
Value float64 `json:"value" tk:"col"`
}
Metric is one sample.
type MetricsOutput ¶
type MetricsOutput struct {
Metrics []Metric `json:"metrics" tk:"rows"`
Dropped int `json:"dropped" jsonschema:"samples with undocumented names, not shown"`
}
MetricsOutput lists documented metrics.
func ParseMetrics ¶
func ParseMetrics(text []byte) MetricsOutput
ParseMetrics parses Prometheus text, keeping documented metric names only.
type NetcheckOutput ¶
type NetcheckOutput struct {
UDP bool `json:"udp"`
IPv4 bool `json:"ipv4"`
IPv6 bool `json:"ipv6"`
IPv4CanSend bool `json:"ipv4CanSend"`
IPv6CanSend bool `json:"ipv6CanSend"`
OSHasIPv6 bool `json:"osHasIpv6"`
ICMPv4 bool `json:"icmpv4"`
MappingVariesByDestIP *bool `json:"mappingVariesByDestIp,omitempty" jsonschema:"hard NAT when true; absent when unknown"`
UPnP *bool `json:"upnp,omitempty" jsonschema:"absent when unknown"`
PMP *bool `json:"pmp,omitempty" jsonschema:"absent when unknown"`
PCP *bool `json:"pcp,omitempty" jsonschema:"absent when unknown"`
CaptivePortal *bool `json:"captivePortal,omitempty" jsonschema:"absent when unknown"`
PreferredDERP int `json:"preferredDerp" jsonschema:"region ID; 0 when unknown"`
RegionLatencyMs map[string]float64 `json:"regionLatencyMs" jsonschema:"keyed by DERP region ID"`
}
NetcheckOutput is the local network report without public IP addresses.
type OAuthApp ¶
type OAuthApp struct {
ID string `json:"id" tk:"col"`
Name string `json:"name" tk:"untrusted,col"`
Description string `json:"description,omitempty" tk:"untrusted"`
RedirectURIs []string `json:"redirectURIs,omitempty" tk:"untrusted,plain"`
Scopes []string `json:"scopes,omitempty" tk:"col"`
AllowedNodeAttributes []string `json:"allowedNodeAttributes,omitempty" tk:"untrusted"`
Created string `json:"created,omitempty"`
Updated string `json:"updated,omitempty"`
}
OAuthApp is an OAuth app without its client secret.
type OAuthAppsOutput ¶
OAuthAppsOutput lists OAuth apps.
type PingInput ¶
type PingInput struct {
Target string `json:"target" jsonschema:"literal tailnet IP of the peer"`
Count int `json:"count,omitempty" jsonschema:"1-10 (default 3)"`
TimeoutSeconds int `json:"timeoutSeconds,omitempty" jsonschema:"per ping, 1-8 (default 5)"`
Mode string `json:"mode,omitempty" jsonschema:"disco (default), tsmp, icmp or peerapi"`
AllPings bool `json:"allPings,omitempty" jsonschema:"send every ping; by default (like the CLI) disco pings stop at the first direct reply"`
}
PingInput configures local_ping.
type PingOutput ¶
type PingOutput struct {
Target string `json:"target"`
Mode string `json:"mode"`
Replies []PingReply `json:"replies" tk:"rows"`
Timeouts int `json:"timeouts"`
DirectEstablished bool `json:"directEstablished"`
DirectNotEstablished bool `json:"directNotEstablished" jsonschema:"the CLI gave up waiting for a direct path"`
NoReply bool `json:"noReply" jsonschema:"no ping was answered"`
UnparsedLines int `json:"unparsedLines"`
Note string `json:"note"`
}
PingOutput summarises a ping run.
type PingReply ¶
type PingReply struct {
Via string `json:"via" tk:"col" jsonschema:"direct, derp, peer-relay, icmp, tsmp or peerapi"`
Region string `json:"region,omitempty" tk:"untrusted,col" jsonschema:"DERP region code, for derp replies"`
LatencyMs float64 `json:"latencyMs" tk:"col"`
}
PingReply is one parsed reply line.
type PingResult ¶
PingResult is what ParsePing extracts from the CLI's stdout.
func ParsePing ¶
func ParsePing(out []byte) PingResult
ParsePing parses `tailscale ping` stdout. Formats are those printed by cmd/tailscale/cli/ping.go; latencies are Go durations ("0s", "12ms", "1.2s").
type Policy ¶
type Policy struct {
Name string `json:"name" tk:"untrusted,col"`
Value string `json:"value" tk:"untrusted,col"`
Origin string `json:"origin,omitempty" tk:"untrusted,col"`
Error string `json:"error,omitempty" tk:"untrusted"`
}
Policy is one effective system policy.
type PolicyProbe ¶ added in v0.6.0
type PolicyProbe struct {
Name string
Status ProbeStatus
Detail string
Fix string
Called bool
Code tkerr.Code
}
PolicyProbe is one row of the policy-mode probes doctor runs. Called is true when the probe made a request, or tried to; a probe that stopped before it asked anything (the canary with no live policy to build on, or a send tailkeeper's own validation limit refused) is not a call. Code is the code of the error the call returned, empty when it returned none. Only the code leaves the probe: the error's text is tailnet text and stays out of this struct.
func ProbePolicyMode ¶ added in v0.6.0
func ProbePolicyMode(ctx context.Context, env *registry.Env) []PolicyProbe
ProbePolicyMode runs the four policy-mode probes, in order: a document the server rejects, the details reader, the in-band canary on the live policy, and one synthetic SSH document. Each send takes one token of the validation bucket. The details read takes none.
type PostureAttribute ¶
type PostureAttribute struct {
Attribute string `json:"attribute" tk:"untrusted,col"`
Value string `json:"value" tk:"untrusted,col"`
Type string `json:"type" tk:"col"`
Expiry string `json:"expiry,omitempty" tk:"col"`
}
PostureAttribute is one device posture attribute.
type PostureIntegration ¶
type PostureIntegration struct {
ID string `json:"id" tk:"col"`
Provider string `json:"provider" tk:"col"`
CloudID string `json:"cloudId,omitempty" tk:"untrusted"`
ClientID string `json:"clientId,omitempty" tk:"untrusted"`
TenantID string `json:"tenantId,omitempty" tk:"untrusted"`
ConfigUpdated string `json:"configUpdated,omitempty"`
Status *PostureStatus `json:"status,omitempty"`
}
PostureIntegration is an EDR/MDM integration without its client secret.
type PostureIntegrationsOutput ¶
type PostureIntegrationsOutput struct {
Integrations []PostureIntegration `json:"integrations" tk:"rows"`
Count int `json:"count"`
}
PostureIntegrationsOutput lists integrations.
type PostureStatus ¶
type PostureStatus struct {
LastSync string `json:"lastSync,omitempty"`
Error string `json:"error,omitempty" tk:"untrusted"`
ProviderHostCount int `json:"providerHostCount"`
MatchedCount int `json:"matchedCount"`
PossibleMatchedCount int `json:"possibleMatchedCount"`
}
PostureStatus is the integration's sync health.
type Pref ¶
type Pref struct {
Name string `json:"name" tk:"col"`
Value string `json:"value" tk:"untrusted,col,plain"`
}
Pref is one client preference.
type PrefsOutput ¶
type PrefsOutput struct {
Prefs []Pref `json:"prefs" tk:"rows"`
}
PrefsOutput lists preferences.
type ProbeStatus ¶ added in v0.6.0
type ProbeStatus string
ProbeStatus is what one policy-mode probe established. A reading tailkeeper did not establish is a warning or a failure, never ok.
const ( ProbeOK ProbeStatus = "ok" ProbeWarn ProbeStatus = "warn" ProbeFail ProbeStatus = "fail" ProbeNA ProbeStatus = "n/a" )
func ClassifyKind ¶ added in v0.6.0
func ClassifyKind(status string, verdicts []string) (st ProbeStatus, detail, fix string)
ClassifyKind is the row for one destination kind. ok only when the test failed and a verdict is allowed or denied. unknown, unresolved and a pass are not that.
type Resolver ¶
type Resolver struct {
Address string `json:"address" tk:"untrusted,plain"`
UseWithExitNode bool `json:"useWithExitNode"`
}
Resolver is one DNS resolver.
type RoutePeer ¶
type RoutePeer struct {
Prefix string `json:"prefix" tk:"untrusted,plain"`
NodeID string `json:"nodeId"`
Name string `json:"name" tk:"untrusted"`
}
RoutePeer is another device serving the same prefix.
type ServeEntry ¶
type ServeEntry struct {
Source string `json:"source" tk:"col" jsonschema:"background, foreground or service"`
Service string `json:"service,omitempty" tk:"untrusted,col" jsonschema:"Tailscale Service name, for source service"`
Listener string `json:"listener" tk:"untrusted,col" jsonschema:"host:port for web listeners, port for TCP"`
Kind string `json:"kind" tk:"col" jsonschema:"web, https, http, tcp-forward or tun"`
Paths []string `json:"paths,omitempty" tk:"untrusted,col"`
Handlers []string `json:"handlers,omitempty" tk:"col" jsonschema:"handler kinds: proxy, path, text or redirect"`
Funnel bool `json:"funnel" tk:"col" jsonschema:"exposed to the public internet"`
}
ServeEntry is one served endpoint. Targets (local ports, file paths, URLs, text) are reduced to their kind.
type ServeOutput ¶
type ServeOutput struct {
Entries []ServeEntry `json:"entries" tk:"rows"`
Count int `json:"count"`
}
ServeOutput lists served endpoints.
func ServeStatus ¶
func ServeStatus(c cliServe, funnelOnly bool) ServeOutput
ServeStatus flattens a serve config: background, then foreground sessions, then Services. Funnel applies to the node's own listeners, not to Services.
type Service ¶
type Service struct {
Name string `json:"name" tk:"untrusted,col"`
DisplayName string `json:"displayName,omitempty" tk:"untrusted"`
Addrs []string `json:"addrs,omitempty" tk:"col"`
Comment string `json:"comment,omitempty" tk:"untrusted"`
Ports []string `json:"ports,omitempty" tk:"untrusted,col"`
Tags []string `json:"tags,omitempty" tk:"untrusted"`
}
Service is a Tailscale Service.
type ServiceRef ¶
type ServiceRef struct {
Name string `json:"name" jsonschema:"service name, for example svc:web"`
}
ServiceRef names one service.
func (ServiceRef) Check ¶ added in v0.6.0
func (in ServiceRef) Check() error
Check refuses a name that cannot be one, before anything is sent.
type ServicesOutput ¶
type ServicesOutput struct {
Services []Service `json:"services" tk:"rows"`
Count int `json:"count"`
}
ServicesOutput lists services.
type Settings ¶
type Settings struct {
DevicesApprovalOn *bool `json:"devicesApprovalOn,omitempty"`
DevicesAutoUpdatesOn *bool `json:"devicesAutoUpdatesOn,omitempty"`
DevicesKeyDurationDays *int `json:"devicesKeyDurationDays,omitempty"`
UsersApprovalOn *bool `json:"usersApprovalOn,omitempty"`
UsersRoleAllowedToJoinExternalTailnets *string `json:"usersRoleAllowedToJoinExternalTailnets,omitempty"`
NetworkFlowLoggingOn *bool `json:"networkFlowLoggingOn,omitempty"`
RegionalRoutingOn *bool `json:"regionalRoutingOn,omitempty"`
RouteSelection *string `json:"routeSelection,omitempty"`
PostureIdentityCollectionOn *bool `json:"postureIdentityCollectionOn,omitempty"`
HTTPSEnabled *bool `json:"httpsEnabled,omitempty"`
ACLsExternallyManagedOn *bool `json:"aclsExternallyManagedOn,omitempty"`
ACLsExternalLink *string `json:"aclsExternalLink,omitempty" tk:"untrusted,plain"`
}
Settings mirrors the API's TailnetSettings. Every field is a pointer: a field the read credential cannot see is absent, and absent must never read as false.
type SettingsOutput ¶
type SettingsOutput struct {
Settings Settings `json:"settings"`
Unreadable []string `` /* 150-byte string literal not displayed */
ExternallyManaged string `json:"externallyManaged" jsonschema:"true, false or unknown"`
}
SettingsOutput reports the settings, which fields could not be read, and the GitOps lock state (spec §11.1).
type SplitDomain ¶
type SplitDomain struct {
Domain string `json:"domain" tk:"untrusted"`
Resolvers []Resolver `json:"resolvers"`
}
SplitDomain is a split-DNS route.
type SubjectResolver ¶ added in v0.6.0
type SubjectResolver struct {
// contains filtered or unexported fields
}
SubjectResolver turns the pseudonym of a user, as a result shows it, into the user's login. It is built for one tool call and dropped with it: it reads the tailnet's users on first use, holds them for the call, and is never kept or shared, since a long-lived process holding every login is the leak this design avoids. The logins it hands out are remembered, so that Hide can mask them where Tailscale's reply repeats them. The logins sit behind a function and Format, so that no fmt verb, no struct holding a resolver and no dumper that follows pointers reaches them. It is not safe for concurrent use.
func NewSubjectResolver ¶ added in v0.6.0
func NewSubjectResolver(env *registry.Env) *SubjectResolver
NewSubjectResolver returns a resolver for one call.
func (SubjectResolver) Format ¶ added in v0.6.0
func (SubjectResolver) Format(f fmt.State, _ rune)
Format keeps every login out of every format verb: fmt calls it before any other way of printing, so even the numeric verbs print "subject resolver". The receiver is a value, so both a SubjectResolver and a pointer to one print it.
func (*SubjectResolver) Hide ¶ added in v0.6.0
func (r *SubjectResolver) Hide(text string) string
Hide is the reverse map: it masks, in text that Tailscale wrote or echoed, every login this resolver has handed out, then every other address, all without pseudonyms. A reply repeats what was sent, and a pseudonym beside it would confirm a guess. The logins are replaced whole and longest first, so a login with a byte the address scan does not read (a slash) is not left half showing. A word glued to the front of a login (bigamy@ for amy@) is another user's address and is masked with it, from its first byte. A marker the text holds is rewritten (the masker's Unforge): Hide appends no pseudonym, so a marker in the result would be one the text forged, and the registry's masking pass does not rewrite it. The result is the head of what a caller sees, hideNeed bytes of it and the rest of the character they end in, whatever the logins in the text were: the text is read as far as it takes for the masked form to reach that, and the work is that of the masked head, not of the text (see read), and stops at hideMaxRead. While personalData is show the text is returned as it came.
func (*SubjectResolver) HideError ¶ added in v0.6.0
func (r *SubjectResolver) HideError(err error) error
HideError returns a copy of err, as a *tkerr.Error, with its message and hint passed through Hide. The code and the HTTP status are kept; the cause is dropped, since it may quote what Hide has just masked.
func (*SubjectResolver) Resolve ¶ added in v0.6.0
Resolve returns the login of the one user that ref names. ref is a pseudonym (p:…), the bracketed form, or a masked value ending in it. It is an error, validation_failed, when ref is none of these, when no user has the pseudonym (the user left, or the privacy key was replaced since the pseudonym was shown), or when several do. No message repeats ref.
func (*SubjectResolver) Shown ¶ added in v0.6.0
func (r *SubjectResolver) Shown(named bool) acl.Show
Shown is how a result of acl_diff or acl_validate shows a piece of a policy, as the engine takes it (acl.Show): the markers it holds are rewritten, every login this resolver has handed out is masked whole, and every other address is masked. With named, the addresses carry the pseudonym acl_get and users_list show for them; without it they carry none (a pseudonym beside an operator's own text would confirm a guess about it, and one beside an echo of a caller's text the same). The engine cuts what it quotes after this has run, so where it cuts is where the shown text says. While personalData is show the text is shown as it is, and the engine's cut is the only one.
func (*SubjectResolver) Typed ¶ added in v0.6.0
func (r *SubjectResolver) Typed(values ...string)
Typed tells the resolver what the caller typed, so that Hide does not treat a quotation of it as the echo of a login the call resolved (see typedValues). It adds to what was told before.
type Supports ¶
type Supports struct {
IPv6 *bool `json:"ipv6,omitempty"`
PCP *bool `json:"pcp,omitempty"`
PMP *bool `json:"pmp,omitempty"`
UDP *bool `json:"udp,omitempty"`
UPnP *bool `json:"upnp,omitempty"`
}
Supports reports NAT traversal features (nil = unknown).
type SyspolicyOutput ¶
type SyspolicyOutput struct {
Scope string `json:"scope,omitempty" tk:"untrusted"`
Policies []Policy `json:"policies" tk:"rows"`
}
SyspolicyOutput lists effective policies.
type User ¶
type User struct {
ID string `json:"id" tk:"col"`
LoginName string `json:"loginName" tk:"untrusted,col,personal"`
DisplayName string `json:"displayName,omitempty" tk:"untrusted,personal"`
TailnetID string `json:"tailnetId,omitempty" tk:"personal"`
Created string `json:"created,omitempty"`
Type string `json:"type" tk:"col"`
Role string `json:"role" tk:"col"`
Status string `json:"status" tk:"col"`
DeviceCount int `json:"deviceCount" tk:"col"`
LastSeen string `json:"lastSeen,omitempty"`
CurrentlyConnected bool `json:"currentlyConnected"`
}
User is a tailnet user.
type UserInvite ¶
type UserInvite struct {
ID string `json:"id" tk:"col"`
Role string `json:"role" tk:"col"`
InviterID int64 `json:"inviterId,omitempty"`
Email string `json:"email,omitempty" tk:"untrusted,col,personal"`
LastEmailSentAt string `json:"lastEmailSentAt,omitempty" tk:"col"`
}
UserInvite is a user invite. inviteUrl is never returned.
type UserInvitesOutput ¶
type UserInvitesOutput struct {
Invites []UserInvite `json:"invites" tk:"rows"`
Count int `json:"count"`
}
UserInvitesOutput lists open user invites.
type UserRef ¶
type UserRef struct {
ID string `json:"id" jsonschema:"user ID"`
}
UserRef names one user.
type UsersListInput ¶
type UsersListInput struct {
Type string `json:"type,omitempty" jsonschema:"member, shared or all (default all; the API's own default hides shared users)"`
Role string `json:"role,omitempty" jsonschema:"owner, member, admin, it-admin, network-admin, billing-admin, auditor or all (default all)"`
}
UsersListInput filters users. Unlike the API, type defaults to all.
func (UsersListInput) Check ¶ added in v0.6.0
func (in UsersListInput) Check() error
Check refuses a type or a role Tailscale does not have, before anything is sent.
type UsersListOutput ¶
type UsersListOutput struct {
Users []User `json:"users" tk:"rows"`
Count int `json:"count"`
Type string `json:"type"`
}
UsersListOutput lists users.
type VersionOutput ¶
type VersionOutput struct {
CLI string `json:"cli" tk:"untrusted"`
Daemon string `json:"daemon,omitempty" tk:"untrusted"`
OSVariant string `json:"osVariant,omitempty" tk:"untrusted"`
Skew bool `json:"skew" jsonschema:"CLI and daemon release versions differ"`
Warnings []string `json:"warnings" tk:"untrusted"`
}
VersionOutput reports CLI and daemon versions.
type Webhook ¶
type Webhook struct {
EndpointID string `json:"endpointId" tk:"col"`
EndpointHost string `json:"endpointHost" tk:"untrusted,col,plain"`
EndpointPathHash string `json:"endpointPathSha256,omitempty"`
ProviderType string `json:"providerType,omitempty" tk:"col"`
CreatorLoginName string `json:"creatorLoginName,omitempty" tk:"untrusted,personal"`
Created string `json:"created,omitempty"`
LastModified string `json:"lastModified,omitempty"`
Subscriptions []string `json:"subscriptions"`
}
Webhook is a webhook endpoint. The secret is never returned, and the endpoint URL is reduced to scheme and host plus a hash of the path, because chat-provider webhook URLs carry a bearer token in the path.
type WebhookRef ¶
type WebhookRef struct {
ID string `json:"id" jsonschema:"webhook endpoint ID"`
}
WebhookRef names one webhook.
func (WebhookRef) Check ¶ added in v0.6.0
func (in WebhookRef) Check() error
Check refuses an ID that cannot be one, before anything is sent.
type WebhooksOutput ¶
type WebhooksOutput struct {
Webhooks []Webhook `json:"webhooks" tk:"rows"`
Count int `json:"count"`
}
WebhooksOutput lists webhooks.
type WhoisInput ¶
type WhoisInput struct {
Address string `json:"address" jsonschema:"tailnet IP, or IP:port"`
Proto string `json:"proto,omitempty" jsonschema:"tcp or udp (with a port); empty means both"`
}
WhoisInput names a tailnet address, optionally with a port.
Source Files
¶
- acl.go
- acl_canary.go
- acl_diff.go
- acl_get.go
- acl_history.go
- acl_invariants.go
- acl_probe.go
- acl_problems.go
- acl_subject_rule.go
- acl_subjects.go
- acl_subjects_hide.go
- acl_subjects_subst.go
- acl_test_echo.go
- acl_test_input.go
- acl_test_messages.go
- acl_test_posture.go
- acl_test_ssh.go
- acl_test_subjects.go
- acl_test_tool.go
- acl_test_verdicts.go
- acl_validate.go
- acl_validate_online.go
- acl_validate_patch.go
- acl_verdicts.go
- acl_version.go
- acl_view.go
- common.go
- cut.go
- devices.go
- dns.go
- dns_attrs.go
- dns_policy.go
- integrations.go
- invites.go
- keys_users.go
- local.go
- logs.go
- result_budget.go
- settings.go