Skip to content

Commit 208899a

Browse files
authored
Merge branch 'main' into adding-playwright
2 parents c8c052e + 78859fd commit 208899a

File tree

6 files changed

+125
-2
lines changed

6 files changed

+125
-2
lines changed

.claude/settings.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,41 @@
77
"permissions": {
88
"additionalDirectories": [
99
"/mnt/data/crucible"
10+
],
11+
"deny": [
12+
"Bash(gh api *)",
13+
"Bash(gh alias delete *)",
14+
"Bash(gh auth logout *)",
15+
"Bash(gh cache delete *)",
16+
"Bash(gh codespace delete *)",
17+
"Bash(gh codespace rebuild *)",
18+
"Bash(gh config clear-cache *)",
19+
"Bash(gh extension remove *)",
20+
"Bash(gh gist delete *)",
21+
"Bash(gh gpg-key delete *)",
22+
"Bash(gh issue delete *)",
23+
"Bash(gh issue transfer *)",
24+
"Bash(gh label delete *)",
25+
"Bash(gh project close *)",
26+
"Bash(gh project delete *)",
27+
"Bash(gh project field-delete *)",
28+
"Bash(gh project item-delete *)",
29+
"Bash(gh project item-archive *)",
30+
"Bash(gh release delete *)",
31+
"Bash(gh release delete-asset *)",
32+
"Bash(gh repo archive *)",
33+
"Bash(gh repo delete *)",
34+
"Bash(gh repo deploy-key delete *)",
35+
"Bash(gh repo rename *)",
36+
"Bash(gh repo transfer *)",
37+
"Bash(gh repo unarchive *)",
38+
"Bash(gh repo visibility *)",
39+
"Bash(gh run cancel *)",
40+
"Bash(gh run delete *)",
41+
"Bash(gh secret delete *)",
42+
"Bash(gh ssh-key delete *)",
43+
"Bash(gh variable delete *)",
44+
"Bash(gh workflow disable *)"
1045
]
1146
}
1247
}

.devcontainer/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ setopt HIST_VERIFY # don't immediately execute recalled commands
111111
# DEVCONTAINER ZSH HISTORY END
112112
EOF
113113
114+
# Export GitHub token from gh CLI for MCP server auth
115+
RUN echo '' >> /home/vscode/.zshrc && \
116+
echo '# GitHub MCP token from gh CLI' >> /home/vscode/.zshrc && \
117+
echo 'export GITHUB_PERSONAL_ACCESS_TOKEN=$(gh auth token 2>/dev/null)' >> /home/vscode/.zshrc
118+
114119
# Switch back to vscode user
115120
USER vscode
116121

.devcontainer/devcontainer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
"source=crucible-dev-claude,target=/home/vscode/.claude,type=volume",
5858
// SSH keys and config
5959
"source=crucible-dev-ssh,target=/home/vscode/.ssh,type=volume",
60+
// GitHub CLI auth
61+
"source=crucible-dev-gh,target=/home/vscode/.config/gh,type=volume",
6062
// MSBuild files for local library development
6163
"source=${localWorkspaceFolder}/.devcontainer/msbuild/Directory.Build.props,target=/mnt/data/Directory.Build.props,type=bind",
6264
"source=${localWorkspaceFolder}/.devcontainer/msbuild/Directory.Build.targets,target=/mnt/data/Directory.Build.targets,type=bind"

Crucible.AppHost/AppHost.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ private static IResourceBuilder<ExecutableResource> AddAngularUI(
117117
else
118118
{
119119
var buildCommand = string.IsNullOrEmpty(buildArgs) ? "npm run build" : $"npm run build {buildArgs}";
120-
var serveProd = $"if [ ! -d {distPath} ] || [ -z \"$(ls -A {distPath} 2>/dev/null)\" ] || [ -n \"$(find src -newer {distPath} -print -quit)\" ]; then npm install && {buildCommand}; fi; npx serve -s {distPath} -l {port}";
120+
var serveProd = $"if [ ! -d {distPath} ] || [ -z \"$(ls -A {distPath} 2>/dev/null)\" ] || [ -n \"$(find src -newer {distPath} -print -quit)\" ]; then npm install && {buildCommand}; fi; echo '{{\"cleanUrls\":false,\"rewrites\":[{{\"source\":\"**\",\"destination\":\"/index.html\"}}]}}' > {distPath}/serve.json && npx serve -c serve.json {distPath} -l {port}";
121121
ui = builder.AddExecutable(name, "bash", appRoot, "-c", serveProd)
122122
.WithHttpEndpoint(port: port, isProxied: false);
123123
}

Crucible.AppHost/resources/crucible-realm.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"defaultSignatureAlgorithm": "RS256",
66
"revokeRefreshToken": false,
77
"refreshTokenMaxReuse": 0,
8-
"accessTokenLifespan": 300,
8+
"accessTokenLifespan": 1800,
99
"accessTokenLifespanForImplicitFlow": 900,
1010
"ssoSessionIdleTimeout": 1800,
1111
"ssoSessionMaxLifespan": 36000,

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Development Environment for [Crucible](https://github.com/cmu-sei/crucible) - a
1313
- [Default Credentials](#default-credentials)
1414
- [Claude Code](#claude-code)
1515
- [Playwright Testing](#playwright-testing)
16+
- [GitHub CLI](#github-cli)
1617
- [Memory Optimization](#memory-optimization)
1718
- [Intelephense PHP Extension](#intelephense-php-extension)
1819
- [UI Development vs Production Mode](#ui-development-vs-production-mode)
@@ -218,6 +219,86 @@ All service URLs used by the test suite are defined in a single file:
218219
```
219220

220221
Edit this file to change ports or hostnames for your environment. The `.env` file is loaded by both the shell scripts (`run-tests.sh`, `setup.sh`) and the Playwright TypeScript configuration. If the file is missing, all URLs fall back to their default `localhost` values.
222+
## GitHub CLI
223+
224+
The dev container includes the [GitHub CLI](https://cli.github.com/) (`gh`). The GitHub CLI's authentication is reused by the GitHub MCP server for agentic development.
225+
226+
### Authentication
227+
228+
GitHub CLI authentication is **persisted across container rebuilds** using a bind mount. Credentials stored via `gh auth login` are saved and automatically available inside the container after a rebuild.
229+
230+
To authenticate for the first time:
231+
232+
```bash
233+
gh auth login
234+
```
235+
236+
Follow the prompts to authenticate via browser or token.
237+
238+
### Recommended: Use a Fine-Grained Personal Access Token
239+
240+
We strongly recommend authenticating with a **fine-grained personal access token (PAT)** rather than a full OAuth login. Fine-grained PATs let you limit exactly what `gh` can do on your behalf.
241+
242+
**To create a fine-grained PAT:**
243+
244+
1. Go to **GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens**
245+
2. Click **Generate new token**
246+
3. Set an expiration date
247+
4. Under **Repository access**, select only the repositories relevant to your work
248+
5. Under **Permissions**, grant only what you need — a reasonable read-heavy baseline:
249+
250+
| Permission | Access |
251+
|---|---|
252+
| Contents | Read-only |
253+
| Issues | Read and write |
254+
| Pull requests | Read and write |
255+
| Metadata | Read-only (required) |
256+
| Actions | Read-only |
257+
| Secrets | None |
258+
| Administration | None |
259+
260+
6. Click **Generate token**, copy it, then run:
261+
262+
```bash
263+
gh auth login --with-token <<< "your_token_here"
264+
```
265+
266+
> Avoid granting `Administration`, `Secrets`, or `Members` permissions — these allow destructive or sensitive operations that are unlikely to be needed during normal development.
267+
268+
### Claude Code Restrictions
269+
270+
To prevent accidental or unintended destructive actions, Claude Code has been configured to **deny** the following `gh` commands in `.claude/settings.json`:
271+
272+
**Raw API access**
273+
- `gh api` — bypasses all CLI safeguards; denied entirely
274+
275+
**Delete operations**
276+
- `gh alias delete`, `gh cache delete`, `gh codespace delete`
277+
- `gh extension remove`, `gh gist delete`, `gh gpg-key delete`
278+
- `gh issue delete`, `gh label delete`
279+
- `gh project delete`, `gh project field-delete`, `gh project item-delete`, `gh project item-archive`
280+
- `gh release delete`, `gh release delete-asset`
281+
- `gh repo delete`, `gh repo deploy-key delete`
282+
- `gh run delete`, `gh secret delete`, `gh ssh-key delete`, `gh variable delete`
283+
284+
**Repository state changes**
285+
- `gh repo archive`, `gh repo unarchive`
286+
- `gh repo rename`, `gh repo transfer`
287+
- `gh repo visibility` — prevents accidentally making a private repo public
288+
289+
**Operational disruption**
290+
- `gh run cancel` — halts CI runs
291+
- `gh workflow disable` — disables automation
292+
- `gh issue transfer` — moves issues to other repos
293+
- `gh codespace rebuild` — destroys current codespace state
294+
295+
**Credential operations**
296+
- `gh auth logout` — removes stored credentials
297+
- `gh config clear-cache` — wipes cached auth data
298+
299+
Claude will be blocked from running any of the above and will need to ask you to run them manually if they are genuinely required.
300+
301+
221302

222303
## Memory Optimization
223304

0 commit comments

Comments
 (0)