tracebit-python 0.1.0__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 (26) hide show
  1. {tracebit_python-0.1.0/src/tracebit_python.egg-info → tracebit_python-0.1.2}/PKG-INFO +85 -27
  2. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/README.md +82 -26
  3. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/pyproject.toml +7 -1
  4. tracebit_python-0.1.2/src/tracebit/__init__.py +1 -0
  5. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit/aws.py +8 -0
  6. tracebit_python-0.1.2/src/tracebit/cli.py +763 -0
  7. tracebit_python-0.1.2/src/tracebit/ssh.py +126 -0
  8. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit/state.py +14 -3
  9. {tracebit_python-0.1.0 → tracebit_python-0.1.2/src/tracebit_python.egg-info}/PKG-INFO +85 -27
  10. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/SOURCES.txt +7 -1
  11. tracebit_python-0.1.2/src/tracebit_python.egg-info/requires.txt +4 -0
  12. tracebit_python-0.1.2/tests/test_api.py +89 -0
  13. tracebit_python-0.1.2/tests/test_aws.py +140 -0
  14. tracebit_python-0.1.2/tests/test_config.py +60 -0
  15. tracebit_python-0.1.2/tests/test_ssh.py +197 -0
  16. tracebit_python-0.1.2/tests/test_state.py +159 -0
  17. tracebit_python-0.1.0/src/tracebit/__init__.py +0 -1
  18. tracebit_python-0.1.0/src/tracebit/cli.py +0 -435
  19. tracebit_python-0.1.0/src/tracebit_python.egg-info/requires.txt +0 -1
  20. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/LICENSE +0 -0
  21. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/setup.cfg +0 -0
  22. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit/api.py +0 -0
  23. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit/config.py +0 -0
  24. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/dependency_links.txt +0 -0
  25. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/entry_points.txt +0 -0
  26. {tracebit_python-0.1.0 → tracebit_python-0.1.2}/src/tracebit_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tracebit-python
3
- Version: 0.1.0
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
@@ -21,6 +21,8 @@ Requires-Python: >=3.8
21
21
  Description-Content-Type: text/markdown
22
22
  License-File: LICENSE
23
23
  Requires-Dist: requests>=2.20
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0; extra == "dev"
24
26
  Dynamic: license-file
25
27
 
26
28
  # tracebit-python
@@ -74,33 +76,46 @@ Or use an environment variable:
74
76
  export TRACEBIT_API_TOKEN=your-token-here
75
77
  ```
76
78
 
77
- ### 3. Deploy a canary
79
+ ### 3. Deploy canaries
80
+
81
+ **AWS credentials:**
78
82
 
79
83
  ```bash
80
84
  tracebit deploy aws --profile staging
81
85
  ```
82
86
 
83
- This issues canary AWS credentials from Tracebit, writes them to
84
- `~/.aws/credentials` under the specified profile, and confirms the
85
- deployment. If anyone (or anything) uses these credentials, Tracebit
86
- 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.
87
102
 
88
103
  ### 4. Test it
89
104
 
90
105
  ```bash
91
- tracebit trigger aws
106
+ tracebit trigger aws # uses aws sts get-caller-identity
107
+ tracebit trigger ssh # connects to Tracebit's honeypot
92
108
  ```
93
109
 
94
- Runs `aws sts get-caller-identity` against the canary profile. You should
95
- 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.
96
111
 
97
112
  ### 5. Keep credentials fresh
98
113
 
99
- Canary credentials expire after ~24 hours. Set up a cron job to refresh them:
114
+ Canary credentials expire after ~12 hours. Set up a cron job:
100
115
 
101
116
  ```bash
102
- # crontab -e
103
- 0 */12 * * * /path/to/tracebit refresh
117
+ tracebit install-cron # prints a ready-to-paste crontab line
118
+ tracebit install-cron --install # adds it to your crontab automatically
104
119
  ```
105
120
 
106
121
  ## Commands
@@ -122,8 +137,25 @@ Issue and deploy canary AWS credentials.
122
137
  | `--labels` | | Metadata as `key=value` pairs |
123
138
  | `--force` | | Replace existing profile (expires old canary first) |
124
139
 
125
- Choose a realistic profile name — `staging`, `backup`, `legacy-admin`, etc.
126
- 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`).
127
159
 
128
160
  ### `tracebit refresh`
129
161
 
@@ -132,23 +164,28 @@ from cron.
132
164
 
133
165
  | Option | Default | Description |
134
166
  |--------|---------|-------------|
135
- | `--hours` | `13` | Refresh credentials expiring within this many hours |
136
-
137
- With 24h credentials and a 12h cron, the default of 13 hours ensures every
138
- cron run refreshes credentials.
167
+ | `--hours` | `2` | Refresh credentials expiring within this many hours |
139
168
 
140
169
  ### `tracebit trigger aws`
141
170
 
142
- 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
143
172
  profile. Requires the AWS CLI to be installed.
144
173
 
145
174
  | Option | Default | Description |
146
175
  |--------|---------|-------------|
147
176
  | `--name` | first found | Credential name to trigger |
148
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
+
149
186
  ### `tracebit show`
150
187
 
151
- Display deployed canary credentials, their profiles, and expiration status.
188
+ Display deployed canary credentials, their profiles/keys, and expiration status.
152
189
 
153
190
  ### `tracebit remove`
154
191
 
@@ -158,6 +195,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
158
195
  |--------|---------|-------------|
159
196
  | `--name` | all | Name of credential to remove |
160
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
+
161
208
  ## Global Options
162
209
 
163
210
  | Option | Description |
@@ -165,6 +212,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
165
212
  | `--token TOKEN` | API token (overrides env var and config file) |
166
213
  | `--base-url URL` | Override Tracebit API URL |
167
214
  | `--json` | JSON output (where supported) |
215
+ | `-q / --quiet` | Suppress informational output (errors still go to stderr) |
168
216
 
169
217
  ## Token Resolution
170
218
 
@@ -176,22 +224,32 @@ The API token is resolved in this order:
176
224
 
177
225
  ## How It Works
178
226
 
227
+ **AWS canaries:**
228
+
179
229
  1. **Issue** — requests canary AWS credentials from the Tracebit API
180
230
  2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
181
- under the chosen profile name
182
- 3. **Confirm** — tells Tracebit the credentials were deployed, so it starts
183
- monitoring for usage
184
- 4. **Alert** — any AWS API call using these credentials triggers a detection
185
- 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
186
233
 
187
234
  The credentials have an explicit deny policy — they can't actually do anything
188
- in AWS. But any attempt to use them (by an attacker who found them on disk,
189
- 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
190
245
 
191
246
  ## File Permissions
192
247
 
193
248
  - `~/.aws/` directory: `0700`
194
249
  - `~/.aws/credentials`, `~/.aws/config`: `0600`
250
+ - `~/.ssh/` directory: `0700`
251
+ - `~/.ssh/<key-file>`: `0600`
252
+ - `~/.ssh/config`: `0600`
195
253
  - `~/.config/tracebit/token`: `0600`
196
254
  - `~/.config/tracebit/state.json`: `0600`
197
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 ~24 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 */12 * * * /path/to/tracebit refresh
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
 
@@ -107,23 +137,28 @@ from cron.
107
137
 
108
138
  | Option | Default | Description |
109
139
  |--------|---------|-------------|
110
- | `--hours` | `13` | Refresh credentials expiring within this many hours |
111
-
112
- With 24h credentials and a 12h cron, the default of 13 hours ensures every
113
- cron run refreshes credentials.
140
+ | `--hours` | `2` | Refresh credentials expiring within this many hours |
114
141
 
115
142
  ### `tracebit trigger aws`
116
143
 
117
- 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
118
145
  profile. Requires the AWS CLI to be installed.
119
146
 
120
147
  | Option | Default | Description |
121
148
  |--------|---------|-------------|
122
149
  | `--name` | first found | Credential name to trigger |
123
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
+
124
159
  ### `tracebit show`
125
160
 
126
- Display deployed canary credentials, their profiles, and expiration status.
161
+ Display deployed canary credentials, their profiles/keys, and expiration status.
127
162
 
128
163
  ### `tracebit remove`
129
164
 
@@ -133,6 +168,16 @@ Remove canary credentials locally and expire them on Tracebit's server.
133
168
  |--------|---------|-------------|
134
169
  | `--name` | all | Name of credential to remove |
135
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
+
136
181
  ## Global Options
137
182
 
138
183
  | Option | Description |
@@ -140,6 +185,7 @@ Remove canary credentials locally and expire them on Tracebit's server.
140
185
  | `--token TOKEN` | API token (overrides env var and config file) |
141
186
  | `--base-url URL` | Override Tracebit API URL |
142
187
  | `--json` | JSON output (where supported) |
188
+ | `-q / --quiet` | Suppress informational output (errors still go to stderr) |
143
189
 
144
190
  ## Token Resolution
145
191
 
@@ -151,22 +197,32 @@ The API token is resolved in this order:
151
197
 
152
198
  ## How It Works
153
199
 
200
+ **AWS canaries:**
201
+
154
202
  1. **Issue** — requests canary AWS credentials from the Tracebit API
155
203
  2. **Deploy** — writes them to `~/.aws/credentials` and `~/.aws/config`
156
- under the chosen profile name
157
- 3. **Confirm** — tells Tracebit the credentials were deployed, so it starts
158
- monitoring for usage
159
- 4. **Alert** — any AWS API call using these credentials triggers a detection
160
- 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
161
206
 
162
207
  The credentials have an explicit deny policy — they can't actually do anything
163
- in AWS. But any attempt to use them (by an attacker who found them on disk,
164
- 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
165
218
 
166
219
  ## File Permissions
167
220
 
168
221
  - `~/.aws/` directory: `0700`
169
222
  - `~/.aws/credentials`, `~/.aws/config`: `0600`
223
+ - `~/.ssh/` directory: `0700`
224
+ - `~/.ssh/<key-file>`: `0600`
225
+ - `~/.ssh/config`: `0600`
170
226
  - `~/.config/tracebit/token`: `0600`
171
227
  - `~/.config/tracebit/state.json`: `0600`
172
228
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tracebit-python"
7
- version = "0.1.0"
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"
@@ -28,6 +28,9 @@ classifiers = [
28
28
  ]
29
29
  dependencies = ["requests>=2.20"]
30
30
 
31
+ [project.optional-dependencies]
32
+ dev = ["pytest>=7.0"]
33
+
31
34
  [project.urls]
32
35
  Repository = "https://github.com/SiteRelEnby/tracebit-python"
33
36
  Issues = "https://github.com/SiteRelEnby/tracebit-python/issues"
@@ -37,3 +40,6 @@ tracebit = "tracebit.cli:main"
37
40
 
38
41
  [tool.setuptools.packages.find]
39
42
  where = ["src"]
43
+
44
+ [tool.pytest.ini_options]
45
+ testpaths = ["tests"]
@@ -0,0 +1 @@
1
+ __version__ = "0.1.2"
@@ -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):