Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ obsidian-web-clipper-settings.json

# Machine-local: pins per-machine plugin versions/cache paths, churns on autoUpdate
factory/.factory/plugins/installed_plugins.json

# AWS credentials and the SSO token cache. Only aws/.aws/config is tracked;
# these are listed so a stray copy into the package can never be committed.
aws/.aws/credentials
aws/.aws/sso/
aws/.aws/cli/
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ GNU Stow-based dotfiles for macOS. Each top-level directory is a stow package mi
Library/... # macOS paths (cursor/, vscode/, nightly-maintenance/)
.claude/ # claude code settings (claude/)
.cargo/, .docker/ # tool config (cargo/, docker/)
.aws/config # aws cli profiles (aws/) — credentials and SSO cache untracked
.githooks/ # git hooks (core.hooksPath); post-merge updates submodules
.claude/skills/ # repo-committed Claude Code skills (deploy — roll main out to all machines)
.retired/ # reference-only packages (yabai, skhd-zig); dot-dirs aren't stowed
Expand All @@ -27,3 +28,4 @@ bootstrap.sh # installs deps, stows packages, git hooks, tailnet ssh, mac
- XDG paths (`.config/`) where the app supports it, macOS `Library/` paths otherwise.
- Every top-level directory is a stow package.
- The `claude/` package has a `.stow-local-ignore` — check it before adding files.
- Packages listed in `bootstrap.sh`'s `NO_FOLDING` (`aws`, `codex`) target directories that also hold host-local state; stow links their files individually so the directory itself is never replaced.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ GNU Stow-based dotfiles for macOS (with Linux support for the CLI packages). Eac
| Package | What it configures |
|---------|--------------------|
| alacritty | Alacritty terminal |
| aws | AWS CLI profiles and Identity Center session |
| cargo | Cargo (Rust) |
| claude | Claude Code settings and permissions |
| codex | Codex global instructions, portable defaults, and core plugins |
Expand Down Expand Up @@ -42,6 +43,8 @@ cd ~/.dotfiles

`bootstrap.sh` installs cross-platform dependencies (stow, zsh, neovim, gh, starship, mise, and Claude Code). On macOS it also installs the Coder CLI and brew casks. It then stows all packages, configures git hooks, and authorizes tailnet SSH between machines. Safe to re-run. macOS-only packages (cursor, duti, nightly-maintenance, teams-link, vscode, wallpapers) are skipped on Linux.

The `aws` package tracks only `~/.aws/config`. Credentials and the Identity Center token cache stay host-local and untracked, so bootstrap stows this package without folding, like `codex`. Account IDs mirror the infra repo's `data/accounts.json`, which is their source of truth.

Codex portable defaults live in `codex/system/config.toml` and bootstrap installs them as `/etc/codex/config.toml`. Codex owns `~/.codex/config.toml` as host-local mutable state for project trust, UI preferences, local runtimes, connectors, and plugin metadata; dotfiles never links or edits it. Bootstrap updates the AWS and Tractorbeam plugin marketplaces, removes Tractorbeam plugins absent from `codex/system/plugins.txt`, and installs every plugin listed there for the ChatGPT desktop app and Codex CLI.

To stow manually:
Expand Down
103 changes: 103 additions & 0 deletions aws/.aws/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# AWS CLI profiles. Only this file is stowed — ~/.aws/sso, ~/.aws/cli, and
# ~/.aws/credentials are host-local cache and secrets, never tracked.
#
# Account IDs come from the infra repo's data/accounts.json, which is the
# single source of truth. Add an account there first, then mirror it here.

[default]
region = us-east-1

# Every profile below authenticates through this one Identity Center session,
# so `aws sso login` once covers all of them.
[sso-session tractorbeam]
sso_start_url = https://tractorbeam.awsapps.com/start/#
sso_region = us-east-1
sso_registration_scopes = sso:account:access

# ── ORGANIZATION ─────────────────────────────────────────────────────────────

[profile root]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 891377101660
sso_role_name = AdministratorAccess

[profile production]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 575108936009
sso_role_name = AdministratorAccess

# Nonprod resolves by assuming OrganizationAccountAccessRole from root rather
# than by a direct Identity Center login. That exact role ARN is what the
# cross-account CodeArtifact trust policies match on (codeartifact-npm-read in
# shared-services, codeartifact-read in distribution), so constellation's
# `mise run secrets:fetch` and a scaffolded project's `mise run
# codeartifact:login` both break if this becomes an ordinary SSO profile.
#
# sso_session is declared alongside the chain purely so `aws sso login` can find
# the session when this profile is active — credentials still resolve through
# assume-role, which precedes sso in the provider chain. Without it, any tool
# that offers to re-authenticate (fnox does) fails on a profile that has no
# sso_start_url of its own.
[profile nonprod]
sso_session = tractorbeam
source_profile = root
role_arn = arn:aws:iam::716174523075:role/OrganizationAccountAccessRole
region = us-east-1

[profile shared-services]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 707264479446
sso_role_name = AdministratorAccess

[profile audit]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 216989103601
sso_role_name = AdministratorAccess

[profile log-archive]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 565393051614
sso_role_name = AdministratorAccess

[profile sandbox]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 545009842244
sso_role_name = AdministratorAccess

# ── PRODUCTS ─────────────────────────────────────────────────────────────────

[profile mailman]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 343508908860
sso_role_name = AdministratorAccess

# ── TESTBEDS ─────────────────────────────────────────────────────────────────
#
# BrizzCo is a fictional customer used to exercise bring-your-own-cloud
# deployments; it holds no real client data.

[profile brizzco]
region = us-east-1
sso_session = tractorbeam
sso_account_id = 237303364471
sso_role_name = AdministratorAccess

# Qualification profiles reach a testbed through the organization role instead
# of an Identity Center assignment, matching how deployment automation lands
# in these accounts.
[profile brizzco-qualification]
source_profile = root
role_arn = arn:aws:iam::237303364471:role/OrganizationAccountAccessRole
region = us-east-1

[profile distribution-qualification]
source_profile = root
role_arn = arn:aws:iam::797601397665:role/OrganizationAccountAccessRole
region = us-east-1
13 changes: 10 additions & 3 deletions bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export PATH="$HOME/.local/bin:$PATH"
# macOS-only stow packages (contain Library/ paths or macOS-only tools)
MACOS_ONLY="cursor duti nightly-maintenance teams-link vscode wallpapers"

# Stow packages whose target directory also holds host-local state, so the
# tracked files must be linked individually rather than by folding the
# directory itself into a symlink.
NO_FOLDING="aws codex"

# CLI packages to install (must exist in brew + apt/dnf/yum/pacman)
PACKAGES=(git neovim stow zsh eza)

Expand Down Expand Up @@ -327,9 +332,11 @@ stow_packages() (
# Pin target to $HOME. Stow's default target is the parent of the stow
# dir, which works when this repo is cloned at ~/dotfiles but not when
# it's elsewhere.
if [[ "$pkg" == "codex" ]]; then
# Codex owns mutable host state under ~/.codex. Link individual global
# instructions without ever replacing the host-local directory.
if [[ " $NO_FOLDING " == *" $pkg "* ]]; then
# These packages sit beside mutable host state — Codex's global
# instructions under ~/.codex, the AWS CLI's SSO token cache and
# credentials under ~/.aws. Link the tracked files individually so stow
# never replaces the host-local directory with a symlink to the repo.
backup_conflicts "$pkg" --no-folding
stow -t "$HOME" --restow --no-folding "$pkg"
else
Expand Down