From 363ba7be4425e8df01f90c95b3cf09bb52e64ada Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 21 Oct 2026 13:56:14 +0000 Subject: [PATCH] hscontrol, servertest: add key list scope golden data Read-only and key-making OAuth tokens of each tag set list auth keys with and without all=true, over admin- and token-made keys of every tag relation, one admin key made after the token-made ones. --- hscontrol/apiv2_compat_test.go | 30 +- .../servertest/testdata/steps/key-list.hujson | 1671 +++++++++++++++++ 2 files changed, 1699 insertions(+), 2 deletions(-) create mode 100644 hscontrol/servertest/testdata/steps/key-list.hujson diff --git a/hscontrol/apiv2_compat_test.go b/hscontrol/apiv2_compat_test.go index cf5369ba4..82a43dd1f 100644 --- a/hscontrol/apiv2_compat_test.go +++ b/hscontrol/apiv2_compat_test.go @@ -1,7 +1,7 @@ // This file replays admin API exchanges captured from Tailscale SaaS, in // order and as the principal SaaS saw, and compares each answer with SaaS's. // -// Test data source: servertest/testdata/steps/{oauth,policy-api}.hujson, +// Test data source: servertest/testdata/steps/{oauth,policy-api,key-list}.hujson, // loaded by name. oauth's late joins are also replayed with real clients by // TestAPIv2OAuthClientDeleteCompat in servertest. // Source format: github.com/juanfont/headscale/hscontrol/types/testcapture @@ -67,6 +67,11 @@ var apiv2CompatSkipReasons = map[string]string{ "oauth/B3/0/tags": mintTagsNotEchoed, "oauth/B11/1/tags": mintTagsNotEchoed, + "key-list/setup-token-keys/0/tags": mintTagsNotEchoed, + "key-list/setup-token-keys/2/tags": mintTagsNotEchoed, + "key-list/setup-token-keys/4/tags": mintTagsNotEchoed, + "key-list/setup-token-keys/6/tags": mintTagsNotEchoed, + "oauth/K1/0/status": unknownPropertyRefused, "oauth/K1/0/outcome": unknownPropertyRefused, "oauth/K1/1/status": unknownPropertyRefused, @@ -104,6 +109,12 @@ var apiv2CompatSkipReasons = map[string]string{ "oauth/B11/2/listed": keyListWithoutAll, "oauth/D0/2/listed": keyListInvalidKeys, + "key-list/L-untagged/1/listed": keyListWithoutAll, + "key-list/L-prod/1/listed": keyListWithoutAll, + "key-list/L-prod-server/1/listed": keyListWithoutAll, + "key-list/L-make-prod/0/listed": keyListWithoutAll, + "key-list/L-make-prod-server/0/listed": keyListWithoutAll, + "oauth/D7/2/status": deletedClientGone, "oauth/D7/2/outcome": deletedClientGone, "oauth/D7/3/message": deletedClientCredentialText, @@ -121,6 +132,12 @@ var apiv2CompatSkipReasons = map[string]string{ "oauth/key:K-prod/creator-user-id": taggedKeyNoUserID, "policy-api/key:J-server/creator-user-id": taggedKeyNoUserID, + "key-list/key:A-db/creator-user-id": taggedKeyNoUserID, + "key-list/key:A-late-prod/creator-user-id": taggedKeyNoUserID, + "key-list/key:A-prod-db/creator-user-id": taggedKeyNoUserID, + "key-list/key:A-prod-server/creator-user-id": taggedKeyNoUserID, + "key-list/key:A-prod/creator-user-id": taggedKeyNoUserID, + "oauth/device:before/all/device-oauth-client": deviceOAuthClientID, "oauth/device:ci-runner/all/device-oauth-client": deviceOAuthClientID, "oauth/device:joiner/all/device-oauth-client": deviceOAuthClientID, @@ -213,7 +230,7 @@ const ( unknownPropertyRefused = "UNKNOWN_PROPERTY_REFUSED: SaaS ignores a createKey property it does not define; headscale refuses the body with 422, so the key is never made" unknownKeyType = "UNKNOWN_KEY_TYPE: SaaS refuses an unknown keyType with 400 before it checks scopes; headscale makes an auth key from it" tagRefusalStatus = "TAG_REFUSAL_STATUS: SaaS refuses a tag outside the token's grant with 400 requested tags are invalid or not permitted; headscale with 403" - keyListWithoutAll = "KEY_LIST_WITHOUT_ALL: without all=true SaaS lists a token only some auth keys, none to an untagged one; headscale lists every key" + keyListWithoutAll = "KEY_LIST_WITHOUT_ALL: without all=true SaaS lists an OAuth token only the auth keys OAuth tokens made, whatever its tags and theirs; headscale lists every key" keyListInvalidKeys = "KEY_LIST_INVALID_KEYS: SaaS leaves spent and revoked auth keys out of a listing; headscale lists them" deletedClientGone = "DELETED_CLIENT_GONE: SaaS keeps a deleted OAuth client readable as invalid and revoked; headscale removes it" deletedClientCredentialText = "DELETED_CLIENT_CREDENTIAL_TEXT: SaaS refuses a deleted client's secret and tokens with API token invalid; headscale says invalid client credentials and unauthorized" @@ -241,6 +258,15 @@ func TestAPIv2OAuthCompat(t *testing.T) { runAPICompat(t, "oauth", false) } +// TestAPIv2KeyListCompat replays auth key listings, with and without +// all=true, by read-only OAuth tokens untagged and of one and two tags and +// by the tokens that made keys, over keys of tags inside, overlapping and +// outside theirs that the admin or a token made, an untagged key the admin +// made, and an admin key made after the token-made ones. +func TestAPIv2KeyListCompat(t *testing.T) { + runAPICompat(t, "key-list", false) +} + // TestAPIv2ACLCompat replays policy writes over a fixed baseline: an // identical write, zero-length, newline-only and empty-object bodies, a cut // short body, a failing test, If-Match with a stale and the current ETag and diff --git a/hscontrol/servertest/testdata/steps/key-list.hujson b/hscontrol/servertest/testdata/steps/key-list.hujson new file mode 100644 index 000000000..9d5cc8bee --- /dev/null +++ b/hscontrol/servertest/testdata/steps/key-list.hujson @@ -0,0 +1,1671 @@ +// key-list +// +// Auth keys an OAuth token lists by its tags, with and without all=true +// +// Steps: 11 +// Captured at: 2026-10-21T14:11:52Z +// tool version: saasprobe 084b1d0607d0b0aa51bacbfee2c2150af96a9596 +// schema version: 1 +{ + "schema_version": 1, + "test_id": "key-list", + "description": "Auth keys an OAuth token lists by its tags, with and without all=true", + "captured_at": "2026-10-21T14:11:52.24839482Z", + "tool_version": "saasprobe 084b1d0607d0b0aa51bacbfee2c2150af96a9596", + "tailnet": "odin@example.com", + "input": {"api_response_code": 0, "tailnet": {"dns": { + "magic_dns": false, + "nameservers": null, + "search_paths": null, + "split_dns": null + }, "settings": {}}, "scenario_hujson": "", "full_policy": {"tagOwners": { + "tag:prod": ["odin@example.com"], + "tag:server": ["odin@example.com"], + "tag:db": ["odin@example.com"] + }}}, + "topology": {"users": [ + {"id": 1, "name": "odin", "email": "odin@example.com"}, + {"id": 2, "name": "thor", "email": "thor@example.org"}, + {"id": 3, "name": "freya", "email": "freya@example.com"} + ], "nodes": {}}, + "captures": null, + "steps": [{ + "name": "setup-tailnet", + "at": "2026-10-21T14:11:52.24841642Z", + "note": "no other auth key and no device; the live policy kept for the teardown", + "result": "observed", + "actions": [{ + "kind": "policy", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/acl", + "header": {"Content-Type": "application/hujson"}, + "body": {"tagOwners": { + "tag:db": ["odin@example.com"], + "tag:prod": ["odin@example.com"], + "tag:server": ["odin@example.com"] + }}, + "status": 200, + "resp_header": {"Content-Type": "application/hujson", "ETag": "{etag:1}"}, + "response": {"tagOwners": { + "tag:db": ["odin@example.com"], + "tag:prod": ["odin@example.com"], + "tag:server": ["odin@example.com"] + }}, + "offset_ms": 251 + }] + }, { + "name": "setup-clients", + "at": "2026-10-21T14:11:52.51620515Z", + "result": "observed", + "actions": [{ + "kind": "api", + "client": "C-list", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-list", + "keyType": "client", + "scopes": ["auth_keys:read"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:11:55Z", + "description": "tscap-saasprobe C-list", + "id": "{client:C-list}", + "keyType": "client", + "scopes": ["auth_keys:read"], + "userId": "{unmatched:1}" + }, + "offset_ms": 2000 + }, { + "kind": "api", + "client": "C-list-prod", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-list-prod", + "keyType": "client", + "scopes": ["auth_keys:read"], + "tags": ["tag:prod"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:11:57Z", + "description": "tscap-saasprobe C-list-prod", + "id": "{client:C-list-prod}", + "keyType": "client", + "scopes": ["auth_keys:read"], + "tags": ["tag:prod"], + "userId": "{unmatched:1}" + }, + "offset_ms": 4017 + }, { + "kind": "api", + "client": "C-list-prod-server", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-list-prod-server", + "keyType": "client", + "scopes": ["auth_keys:read"], + "tags": ["tag:prod", "tag:server"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:11:59Z", + "description": "tscap-saasprobe C-list-prod-server", + "id": "{client:C-list-prod-server}", + "keyType": "client", + "scopes": ["auth_keys:read"], + "tags": ["tag:prod", "tag:server"], + "userId": "{unmatched:1}" + }, + "offset_ms": 6034 + }, { + "kind": "api", + "client": "C-make-prod", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-make-prod", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:12:01Z", + "description": "tscap-saasprobe C-make-prod", + "id": "{client:C-make-prod}", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod"], + "userId": "{unmatched:1}" + }, + "offset_ms": 8070 + }, { + "kind": "api", + "client": "C-make-prod-server", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-make-prod-server", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod", "tag:server"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:12:03Z", + "description": "tscap-saasprobe C-make-prod-server", + "id": "{client:C-make-prod-server}", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod", "tag:server"], + "userId": "{unmatched:1}" + }, + "offset_ms": 10087 + }, { + "kind": "api", + "client": "C-make-prod-db", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-make-prod-db", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod", "tag:db"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:12:05Z", + "description": "tscap-saasprobe C-make-prod-db", + "id": "{client:C-make-prod-db}", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:prod", "tag:db"], + "userId": "{unmatched:1}" + }, + "offset_ms": 12104 + }, { + "kind": "api", + "client": "C-make-db", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "description": "tscap-saasprobe C-make-db", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:db"] + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "created": "2026-10-21T14:12:07Z", + "description": "tscap-saasprobe C-make-db", + "id": "{client:C-make-db}", + "keyType": "client", + "scopes": ["auth_keys"], + "tags": ["tag:db"], + "userId": "{unmatched:1}" + }, + "offset_ms": 14123 + }] + }, { + "name": "setup-keys", + "at": "2026-10-21T14:12:06.65670001Z", + "result": "observed", + "actions": [{ + "kind": "api", + "key": "A-user", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": { + "create": {"ephemeral": false, "preauthorized": true, "reusable": true, "tags": null} + }}, "description": "tscap-saasprobe A-user", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 2000 + }, { + "kind": "api", + "key": "A-prod", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, "description": "tscap-saasprobe A-prod", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 4017 + }, { + "kind": "api", + "key": "A-prod-server", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "description": "tscap-saasprobe A-prod-server", + "expirySeconds": 3600 + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 6036 + }, { + "kind": "api", + "key": "A-prod-db", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, "description": "tscap-saasprobe A-prod-db", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 8053 + }, { + "kind": "api", + "key": "A-db", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, "description": "tscap-saasprobe A-db", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 10070 + }] + }, { + "name": "setup-token-keys", + "at": "2026-10-21T14:12:16.748683847Z", + "result": "observed", + "actions": [{ + "kind": "token", + "client": "C-make-prod", + "principal": "token:C-make-prod", + "status": 200, + "response": { + "expires_in": 3600, + "scope": "auth_keys", + "tags": "tag:prod", + "token_type": "Bearer" + }, + "offset_ms": 2000 + }, { + "kind": "api", + "key": "M-prod", + "principal": "token:C-make-prod", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, "description": "tscap-saasprobe M-prod", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, + "offset_ms": 4018 + }, { + "kind": "token", + "client": "C-make-prod-server", + "principal": "token:C-make-prod-server", + "status": 200, + "response": { + "expires_in": 3600, + "scope": "auth_keys", + "tags": "tag:prod tag:server", + "token_type": "Bearer" + }, + "offset_ms": 6035 + }, { + "kind": "api", + "key": "M-prod-server", + "principal": "token:C-make-prod-server", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "description": "tscap-saasprobe M-prod-server", + "expirySeconds": 3600 + }, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, + "offset_ms": 8052 + }, { + "kind": "token", + "client": "C-make-prod-db", + "principal": "token:C-make-prod-db", + "status": 200, + "response": { + "expires_in": 3600, + "scope": "auth_keys", + "tags": "tag:prod tag:db", + "token_type": "Bearer" + }, + "offset_ms": 10069 + }, { + "kind": "api", + "key": "M-prod-db", + "principal": "token:C-make-prod-db", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, "description": "tscap-saasprobe M-prod-db", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, + "offset_ms": 12086 + }, { + "kind": "token", + "client": "C-make-db", + "principal": "token:C-make-db", + "status": 200, + "response": { + "expires_in": 3600, + "scope": "auth_keys", + "tags": "tag:db", + "token_type": "Bearer" + }, + "offset_ms": 14104 + }, { + "kind": "api", + "key": "M-db", + "principal": "token:C-make-db", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, "description": "tscap-saasprobe M-db", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, + "offset_ms": 16123 + }] + }, { + "name": "setup-late-key", + "at": "2026-10-21T14:12:32.888768853Z", + "result": "observed", + "actions": [{ + "kind": "api", + "key": "A-late-prod", + "principal": "admin", + "method": "POST", + "path": "/tailnet/-/keys", + "header": {"Content-Type": "application/json"}, + "body": {"capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, "description": "tscap-saasprobe A-late-prod", "expirySeconds": 3600}, + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, + "offset_ms": 2000 + }] + }, { + "name": "L-untagged", + "at": "2026-10-21T14:12:34.907964891Z", + "result": "observed", + "actions": [{ + "kind": "token", + "client": "C-list", + "principal": "token:C-list", + "status": 200, + "response": {"expires_in": 3600, "scope": "auth_keys:read", "token_type": "Bearer"}, + "offset_ms": 2001 + }, { + "kind": "api", + "principal": "token:C-list", + "method": "GET", + "path": "/tailnet/-/keys", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }]}, + "offset_ms": 2017 + }, { + "kind": "api", + "principal": "token:C-list", + "method": "GET", + "path": "/tailnet/-/keys?all=true", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }]}, + "offset_ms": 2033 + }] + }, { + "name": "L-prod", + "at": "2026-10-21T14:12:36.961535116Z", + "result": "observed", + "actions": [{ + "kind": "token", + "client": "C-list-prod", + "principal": "token:C-list-prod", + "status": 200, + "response": {"expires_in": 3600, "scope": "auth_keys:read", "token_type": "Bearer"}, + "offset_ms": 1965 + }, { + "kind": "api", + "principal": "token:C-list-prod", + "method": "GET", + "path": "/tailnet/-/keys", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }]}, + "offset_ms": 1980 + }, { + "kind": "api", + "principal": "token:C-list-prod", + "method": "GET", + "path": "/tailnet/-/keys?all=true", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }]}, + "offset_ms": 1997 + }] + }, { + "name": "L-prod-server", + "at": "2026-10-21T14:12:38.979961954Z", + "result": "observed", + "actions": [{ + "kind": "token", + "client": "C-list-prod-server", + "principal": "token:C-list-prod-server", + "status": 200, + "response": {"expires_in": 3600, "scope": "auth_keys:read", "token_type": "Bearer"}, + "offset_ms": 1964 + }, { + "kind": "api", + "principal": "token:C-list-prod-server", + "method": "GET", + "path": "/tailnet/-/keys", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }]}, + "offset_ms": 1981 + }, { + "kind": "api", + "principal": "token:C-list-prod-server", + "method": "GET", + "path": "/tailnet/-/keys?all=true", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }]}, + "offset_ms": 1997 + }] + }, { + "name": "L-make-prod", + "at": "2026-10-21T14:12:40.997777183Z", + "result": "observed", + "actions": [{ + "kind": "api", + "principal": "token:C-make-prod", + "method": "GET", + "path": "/tailnet/-/keys", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }]} + }, { + "kind": "api", + "principal": "token:C-make-prod", + "method": "GET", + "path": "/tailnet/-/keys?all=true", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }]}, + "offset_ms": 15 + }] + }, { + "name": "L-make-prod-server", + "at": "2026-10-21T14:12:41.033842713Z", + "result": "observed", + "actions": [{ + "kind": "api", + "principal": "token:C-make-prod-server", + "method": "GET", + "path": "/tailnet/-/keys", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }]} + }, { + "kind": "api", + "principal": "token:C-make-prod-server", + "method": "GET", + "path": "/tailnet/-/keys?all=true", + "status": 200, + "resp_header": {"Content-Type": "application/json"}, + "response": {"keys": [{ + "capabilities": { + "devices": {"create": {"ephemeral": false, "preauthorized": true, "reusable": true}} + }, + "created": "2026-10-21T14:12:09Z", + "description": "tscap-saasprobe A-user", + "expires": "2026-10-21T15:12:09Z", + "expirySeconds": 3600, + "id": "{key:A-user}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:11Z", + "description": "tscap-saasprobe A-prod", + "expires": "2026-10-21T15:12:11Z", + "expirySeconds": 3600, + "id": "{key:A-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:13Z", + "description": "tscap-saasprobe A-prod-server", + "expires": "2026-10-21T15:12:13Z", + "expirySeconds": 3600, + "id": "{key:A-prod-server}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:15Z", + "description": "tscap-saasprobe A-prod-db", + "expires": "2026-10-21T15:12:15Z", + "expirySeconds": 3600, + "id": "{key:A-prod-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:17Z", + "description": "tscap-saasprobe A-db", + "expires": "2026-10-21T15:12:17Z", + "expirySeconds": 3600, + "id": "{key:A-db}", + "keyType": "auth", + "userId": "{unmatched:1}" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:21Z", + "description": "tscap-saasprobe M-prod", + "expires": "2026-10-21T15:12:21Z", + "expirySeconds": 3600, + "id": "{key:M-prod}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:server"] + }}}, + "created": "2026-10-21T14:12:25Z", + "description": "tscap-saasprobe M-prod-server", + "expires": "2026-10-21T15:12:25Z", + "expirySeconds": 3600, + "id": "{key:M-prod-server}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod", "tag:db"] + }}}, + "created": "2026-10-21T14:12:29Z", + "description": "tscap-saasprobe M-prod-db", + "expires": "2026-10-21T15:12:29Z", + "expirySeconds": 3600, + "id": "{key:M-prod-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:db"] + }}}, + "created": "2026-10-21T14:12:33Z", + "description": "tscap-saasprobe M-db", + "expires": "2026-10-21T15:12:33Z", + "expirySeconds": 3600, + "id": "{key:M-db}", + "keyType": "auth" + }, { + "capabilities": {"devices": {"create": { + "ephemeral": false, + "preauthorized": true, + "reusable": true, + "tags": ["tag:prod"] + }}}, + "created": "2026-10-21T14:12:35Z", + "description": "tscap-saasprobe A-late-prod", + "expires": "2026-10-21T15:12:35Z", + "expirySeconds": 3600, + "id": "{key:A-late-prod}", + "keyType": "auth", + "userId": "{unmatched:1}" + }]}, + "offset_ms": 16 + }] + }, { + "name": "retire", + "at": "2026-10-21T14:12:41.069410518Z", + "result": "observed", + "actions": [{"kind": "retire", "args": ["keys", "clients"]}] + }] +}