tracebit-python 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. {tracebit_python-0.1.1/src/tracebit_python.egg-info → tracebit_python-0.1.2}/PKG-INFO +82 -23
  2. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/README.md +81 -22
  3. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/pyproject.toml +1 -1
  4. tracebit_python-0.1.2/src/tracebit/__init__.py +1 -0
  5. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/api.py +1 -1
  6. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/aws.py +8 -0
  7. tracebit_python-0.1.2/src/tracebit/cli.py +763 -0
  8. tracebit_python-0.1.2/src/tracebit/ssh.py +126 -0
  9. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/state.py +14 -3
  10. {tracebit_python-0.1.1 → tracebit_python-0.1.2/src/tracebit_python.egg-info}/PKG-INFO +82 -23
  11. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/SOURCES.txt +2 -0
  12. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_api.py +1 -1
  13. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_aws.py +15 -0
  14. tracebit_python-0.1.2/tests/test_ssh.py +197 -0
  15. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_state.py +30 -0
  16. tracebit_python-0.1.1/src/tracebit/__init__.py +0 -1
  17. tracebit_python-0.1.1/src/tracebit/cli.py +0 -457
  18. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/LICENSE +0 -0
  19. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/setup.cfg +0 -0
  20. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit/config.py +0 -0
  21. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/dependency_links.txt +0 -0
  22. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/entry_points.txt +0 -0
  23. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/requires.txt +0 -0
  24. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/top_level.txt +0 -0
  25. {tracebit_python-0.1.1 → tracebit_python-0.1.2}/tests/test_config.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracebit-python
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: CLI for managing Tracebit canary credentials on headless servers
5
5
  License: Apache-2.0
6
6
  Project-URL: Repository, https://github.com/SiteRelEnby/tracebit-python
@@ -76,33 +76,46 @@ Or use an environment variable:
76
76
  export TRACEBIT_API_TOKEN=your-token-here
77
77
  ```
78
78
 
79
- ### 3. Deploy a canary
79
+ ### 3. Deploy canaries
80
+
81
+ **AWS credentials:**
80
82
 
81
83
  ```bash
82
84
  tracebit deploy aws --profile staging
83
85
  ```
84
86
 
85
- This issues canary AWS credentials from Tracebit, writes them to
86
- `~/.aws/credentials` under the specified profile, and confirms the
87
- deployment. If anyone (or anything) uses these credentials, Tracebit
88
- fires an alert.
87
+ Writes canary AWS credentials to `~/.aws/credentials` under the given profile.
88
+ Any AWS API call using these credentials triggers an alert.
89
+
90
+ **SSH key:**
91
+
92
+ ```bash
93
+ tracebit deploy ssh --key-file id_backup --ssh-host backup-server.internal
94
+ ```
95
+
96
+ Writes a canary SSH private key to `~/.ssh/id_backup` and adds a `Host` block
97
+ to `~/.ssh/config` pointing `backup-server.internal` at Tracebit's honeypot.
98
+ Any SSH connection attempt using this key triggers an alert.
99
+
100
+ Choose names that look realistic to an attacker — `staging`, `id_backup`,
101
+ `backup-server.internal`. The whole point is that they look like real credentials.
89
102
 
90
103
  ### 4. Test it
91
104
 
92
105
  ```bash
93
- tracebit trigger aws
106
+ tracebit trigger aws # uses aws sts get-caller-identity
107
+ tracebit trigger ssh # connects to Tracebit's honeypot
94
108
  ```
95
109
 
96
- Runs `aws sts get-caller-identity` against the canary profile. You should
97
- see an alert on the Tracebit dashboard within a few minutes.
110
+ You should see an alert on the Tracebit dashboard within a few minutes.
98
111
 
99
112
  ### 5. Keep credentials fresh
100
113
 
101
- Canary credentials expire after ~12 hours. Set up a cron job to refresh them:
114
+ Canary credentials expire after ~12 hours. Set up a cron job:
102
115
 
103
116
  ```bash
104
- # crontab -e
105
- 0 */6 * * * /path/to/tracebit refresh --hours 4
117
+ tracebit install-cron # prints a ready-to-paste crontab line
118
+ tracebit install-cron --install # adds it to your crontab automatically
106
119
  ```
107
120
 
108
121
  ## Commands
@@ -124,8 +137,25 @@ Issue and deploy canary AWS credentials.
124
137
  | `--labels` | | Metadata as `key=value` pairs |
125
138
  | `--force` | | Replace existing profile (expires old canary first) |
126
139
 
127
- Choose a realistic profile name — `staging`, `backup`, `legacy-admin`, etc.
128
- The whole point is for these to look like real credentials to an attacker.
140
+ ### `tracebit deploy ssh`
141
+
142
+ Issue and deploy a canary SSH private key.
143
+
144
+ | Option | Default | Description |
145
+ |--------|---------|-------------|
146
+ | `--name` | hostname | Credential name (shown on Tracebit dashboard) |
147
+ | `--key-file` | from API | Key filename in `~/.ssh/` |
148
+ | `--ssh-host` | honeypot IP | Hostname alias for `~/.ssh/config` Host entry |
149
+ | `--ssh-config-file` | `~/.ssh/config` | SSH config file to write Host entry into |
150
+ | `--labels` | | Metadata as `key=value` pairs |
151
+ | `--force` | | Replace existing key/config entry |
152
+
153
+ The `--ssh-host` alias is what makes the canary effective: an attacker finding
154
+ `~/.ssh/config` with `Host backup-server.internal` pointing somewhere will try
155
+ to connect there, firing the alert. If omitted, the honeypot IP is used directly.
156
+
157
+ Use `--ssh-config-file` if your `~/.ssh/config` is tracked in git and you keep
158
+ local overrides in a separate file (e.g. `~/.ssh/config.local`).
129
159
 
130
160
  ### `tracebit refresh`
131
161
 
@@ -138,16 +168,24 @@ from cron.
138
168
 
139
169
  ### `tracebit trigger aws`
140
170
 
141
- Test-fire a canary by calling `aws sts get-caller-identity` with the canary
171
+ Test-fire an AWS canary by calling `aws sts get-caller-identity` with the canary
142
172
  profile. Requires the AWS CLI to be installed.
143
173
 
144
174
  | Option | Default | Description |
145
175
  |--------|---------|-------------|
146
176
  | `--name` | first found | Credential name to trigger |
147
177
 
178
+ ### `tracebit trigger ssh`
179
+
180
+ Test-fire an SSH canary by connecting to Tracebit's honeypot with the canary key.
181
+
182
+ | Option | Default | Description |
183
+ |--------|---------|-------------|
184
+ | `--name` | first found | Credential name to trigger |
185
+
148
186
  ### `tracebit show`
149
187
 
150
- Display deployed canary credentials, their profiles, and expiration status.
188
+ Display deployed canary credentials, their profiles/keys, and expiration status.
151
189
 
152
190
  ### `tracebit remove`
153
191
 
@@ -157,6 +195,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
157
195
  |--------|---------|-------------|
158
196
  | `--name` | all | Name of credential to remove |
159
197
 
198
+ ### `tracebit install-cron`
199
+
200
+ Print or install a cron job that runs `tracebit refresh --quiet` on a schedule.
201
+
202
+ | Option | Default | Description |
203
+ |--------|---------|-------------|
204
+ | `--schedule` | `*/30 * * * *` | Cron schedule expression |
205
+ | `--install` | | Add entry to current user's crontab |
206
+ | `--system` | | Write `/etc/cron.d/tracebit` (requires root) |
207
+
160
208
  ## Global Options
161
209
 
162
210
  | Option | Description |
@@ -164,6 +212,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
164
212
  | `--token TOKEN` | API token (overrides env var and config file) |
165
213
  | `--base-url URL` | Override Tracebit API URL |
166
214
  | `--json` | JSON output (where supported) |
215
+ | `-q / --quiet` | Suppress informational output (errors still go to stderr) |
167
216
 
168
217
  ## Token Resolution
169
218
 
@@ -175,22 +224,32 @@ The API token is resolved in this order:
175
224
 
176
225
  ## How It Works
177
226
 
227
+ **AWS canaries:**
228
+
178
229
  1. **Issue** — requests canary AWS credentials from the Tracebit API
179
230
  2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
180
- under the chosen profile name
181
- 3. **Confirm** — tells Tracebit the credentials were deployed, so it starts
182
- monitoring for usage
183
- 4. **Alert** — any AWS API call using these credentials triggers a detection
184
- on the Tracebit dashboard
231
+ 3. **Confirm** — tells Tracebit the credentials are live
232
+ 4. **Alert** — any AWS API call using these credentials fires a detection
185
233
 
186
234
  The credentials have an explicit deny policy — they can't actually do anything
187
- in AWS. But any attempt to use them (by an attacker who found them on disk,
188
- in a config file, etc.) is logged and alerted on.
235
+ in AWS. But any attempt to use them is logged and alerted on.
236
+
237
+ **SSH canaries:**
238
+
239
+ 1. **Issue** — requests a canary SSH private key from the Tracebit API
240
+ 2. **Deploy** — writes the key to `~/.ssh/<key-file>` and adds a `Host` block
241
+ to `~/.ssh/config` pointing the chosen hostname at Tracebit's honeypot
242
+ 3. **Confirm** — tells Tracebit the key is deployed
243
+ 4. **Alert** — any SSH connection attempt presenting this key to the honeypot
244
+ fires a detection
189
245
 
190
246
  ## File Permissions
191
247
 
192
248
  - `~/.aws/` directory: `0700`
193
249
  - `~/.aws/credentials`, `~/.aws/config`: `0600`
250
+ - `~/.ssh/` directory: `0700`
251
+ - `~/.ssh/<key-file>`: `0600`
252
+ - `~/.ssh/config`: `0600`
194
253
  - `~/.config/tracebit/token`: `0600`
195
254
  - `~/.config/tracebit/state.json`: `0600`
196
255
 
@@ -49,33 +49,46 @@ Or use an environment variable:
49
49
  export TRACEBIT_API_TOKEN=your-token-here
50
50
  ```
51
51
 
52
- ### 3. Deploy a canary
52
+ ### 3. Deploy canaries
53
+
54
+ **AWS credentials:**
53
55
 
54
56
  ```bash
55
57
  tracebit deploy aws --profile staging
56
58
  ```
57
59
 
58
- This issues canary AWS credentials from Tracebit, writes them to
59
- `~/.aws/credentials` under the specified profile, and confirms the
60
- deployment. If anyone (or anything) uses these credentials, Tracebit
61
- fires an alert.
60
+ Writes canary AWS credentials to `~/.aws/credentials` under the given profile.
61
+ Any AWS API call using these credentials triggers an alert.
62
+
63
+ **SSH key:**
64
+
65
+ ```bash
66
+ tracebit deploy ssh --key-file id_backup --ssh-host backup-server.internal
67
+ ```
68
+
69
+ Writes a canary SSH private key to `~/.ssh/id_backup` and adds a `Host` block
70
+ to `~/.ssh/config` pointing `backup-server.internal` at Tracebit's honeypot.
71
+ Any SSH connection attempt using this key triggers an alert.
72
+
73
+ Choose names that look realistic to an attacker — `staging`, `id_backup`,
74
+ `backup-server.internal`. The whole point is that they look like real credentials.
62
75
 
63
76
  ### 4. Test it
64
77
 
65
78
  ```bash
66
- tracebit trigger aws
79
+ tracebit trigger aws # uses aws sts get-caller-identity
80
+ tracebit trigger ssh # connects to Tracebit's honeypot
67
81
  ```
68
82
 
69
- Runs `aws sts get-caller-identity` against the canary profile. You should
70
- see an alert on the Tracebit dashboard within a few minutes.
83
+ You should see an alert on the Tracebit dashboard within a few minutes.
71
84
 
72
85
  ### 5. Keep credentials fresh
73
86
 
74
- Canary credentials expire after ~12 hours. Set up a cron job to refresh them:
87
+ Canary credentials expire after ~12 hours. Set up a cron job:
75
88
 
76
89
  ```bash
77
- # crontab -e
78
- 0 */6 * * * /path/to/tracebit refresh --hours 4
90
+ tracebit install-cron # prints a ready-to-paste crontab line
91
+ tracebit install-cron --install # adds it to your crontab automatically
79
92
  ```
80
93
 
81
94
  ## Commands
@@ -97,8 +110,25 @@ Issue and deploy canary AWS credentials.
97
110
  | `--labels` | | Metadata as `key=value` pairs |
98
111
  | `--force` | | Replace existing profile (expires old canary first) |
99
112
 
100
- Choose a realistic profile name — `staging`, `backup`, `legacy-admin`, etc.
101
- The whole point is for these to look like real credentials to an attacker.
113
+ ### `tracebit deploy ssh`
114
+
115
+ Issue and deploy a canary SSH private key.
116
+
117
+ | Option | Default | Description |
118
+ |--------|---------|-------------|
119
+ | `--name` | hostname | Credential name (shown on Tracebit dashboard) |
120
+ | `--key-file` | from API | Key filename in `~/.ssh/` |
121
+ | `--ssh-host` | honeypot IP | Hostname alias for `~/.ssh/config` Host entry |
122
+ | `--ssh-config-file` | `~/.ssh/config` | SSH config file to write Host entry into |
123
+ | `--labels` | | Metadata as `key=value` pairs |
124
+ | `--force` | | Replace existing key/config entry |
125
+
126
+ The `--ssh-host` alias is what makes the canary effective: an attacker finding
127
+ `~/.ssh/config` with `Host backup-server.internal` pointing somewhere will try
128
+ to connect there, firing the alert. If omitted, the honeypot IP is used directly.
129
+
130
+ Use `--ssh-config-file` if your `~/.ssh/config` is tracked in git and you keep
131
+ local overrides in a separate file (e.g. `~/.ssh/config.local`).
102
132
 
103
133
  ### `tracebit refresh`
104
134
 
@@ -111,16 +141,24 @@ from cron.
111
141
 
112
142
  ### `tracebit trigger aws`
113
143
 
114
- Test-fire a canary by calling `aws sts get-caller-identity` with the canary
144
+ Test-fire an AWS canary by calling `aws sts get-caller-identity` with the canary
115
145
  profile. Requires the AWS CLI to be installed.
116
146
 
117
147
  | Option | Default | Description |
118
148
  |--------|---------|-------------|
119
149
  | `--name` | first found | Credential name to trigger |
120
150
 
151
+ ### `tracebit trigger ssh`
152
+
153
+ Test-fire an SSH canary by connecting to Tracebit's honeypot with the canary key.
154
+
155
+ | Option | Default | Description |
156
+ |--------|---------|-------------|
157
+ | `--name` | first found | Credential name to trigger |
158
+
121
159
  ### `tracebit show`
122
160
 
123
- Display deployed canary credentials, their profiles, and expiration status.
161
+ Display deployed canary credentials, their profiles/keys, and expiration status.
124
162
 
125
163
  ### `tracebit remove`
126
164
 
@@ -130,6 +168,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
130
168
  |--------|---------|-------------|
131
169
  | `--name` | all | Name of credential to remove |
132
170
 
171
+ ### `tracebit install-cron`
172
+
173
+ Print or install a cron job that runs `tracebit refresh --quiet` on a schedule.
174
+
175
+ | Option | Default | Description |
176
+ |--------|---------|-------------|
177
+ | `--schedule` | `*/30 * * * *` | Cron schedule expression |
178
+ | `--install` | | Add entry to current user's crontab |
179
+ | `--system` | | Write `/etc/cron.d/tracebit` (requires root) |
180
+
133
181
  ## Global Options
134
182
 
135
183
  | Option | Description |
@@ -137,6 +185,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
137
185
  | `--token TOKEN` | API token (overrides env var and config file) |
138
186
  | `--base-url URL` | Override Tracebit API URL |
139
187
  | `--json` | JSON output (where supported) |
188
+ | `-q / --quiet` | Suppress informational output (errors still go to stderr) |
140
189
 
141
190
  ## Token Resolution
142
191
 
@@ -148,22 +197,32 @@ The API token is resolved in this order:
148
197
 
149
198
  ## How It Works
150
199
 
200
+ **AWS canaries:**
201
+
151
202
  1. **Issue** — requests canary AWS credentials from the Tracebit API
152
203
  2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
153
- under the chosen profile name
154
- 3. **Confirm** — tells Tracebit the credentials were deployed, so it starts
155
- monitoring for usage
156
- 4. **Alert** — any AWS API call using these credentials triggers a detection
157
- on the Tracebit dashboard
204
+ 3. **Confirm** — tells Tracebit the credentials are live
205
+ 4. **Alert** — any AWS API call using these credentials fires a detection
158
206
 
159
207
  The credentials have an explicit deny policy — they can't actually do anything
160
- in AWS. But any attempt to use them (by an attacker who found them on disk,
161
- in a config file, etc.) is logged and alerted on.
208
+ in AWS. But any attempt to use them is logged and alerted on.
209
+
210
+ **SSH canaries:**
211
+
212
+ 1. **Issue** — requests a canary SSH private key from the Tracebit API
213
+ 2. **Deploy** — writes the key to `~/.ssh/<key-file>` and adds a `Host` block
214
+ to `~/.ssh/config` pointing the chosen hostname at Tracebit's honeypot
215
+ 3. **Confirm** — tells Tracebit the key is deployed
216
+ 4. **Alert** — any SSH connection attempt presenting this key to the honeypot
217
+ fires a detection
162
218
 
163
219
  ## File Permissions
164
220
 
165
221
  - `~/.aws/` directory: `0700`
166
222
  - `~/.aws/credentials`, `~/.aws/config`: `0600`
223
+ - `~/.ssh/` directory: `0700`
224
+ - `~/.ssh/<key-file>`: `0600`
225
+ - `~/.ssh/config`: `0600`
167
226
  - `~/.config/tracebit/token`: `0600`
168
227
  - `~/.config/tracebit/state.json`: `0600`
169
228
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tracebit-python"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "CLI for managing Tracebit canary credentials on headless servers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -0,0 +1 @@
1
+ __version__ = "0.1.2"
@@ -35,7 +35,7 @@ class TracebitClient:
35
35
  source_type="endpoint", labels=None):
36
36
  body = {
37
37
  "name": name,
38
- "credentialTypes": types,
38
+ "types": types,
39
39
  "source": source,
40
40
  "sourceType": source_type,
41
41
  }
@@ -10,6 +10,14 @@ CONFIG_FILE = AWS_DIR / "config"
10
10
 
11
11
  def _ensure_aws_dir():
12
12
  AWS_DIR.mkdir(mode=0o700, exist_ok=True)
13
+ mode = AWS_DIR.stat().st_mode & 0o777
14
+ if mode != 0o700:
15
+ import sys
16
+ print(
17
+ f"Warning: ~/.aws/ has permissions {oct(mode)} (expected 0700). "
18
+ f"Consider running: chmod 700 ~/.aws",
19
+ file=sys.stderr,
20
+ )
13
21
 
14
22
 
15
23
  def _read_ini(path):