Claude Code in Practice: Authentication, Permissions, Hooks, and Rollback for Agentic Coding
Agentic coding tools are evolving from occasional code generators into collaborators in the development workflow. Using Claude Code as an example, this article covers what to settle before daily use: behavioral boundaries, authentication and billing, slash commands, layered configuration, IDE integration, hooks, project memory, checkpoints and rollback, reusable commands and skills, and a pragmatic rollout path. The focus is on controls that keep agent behavior reviewable, permissioned, and recoverable.
Agentic coding tools are moving from “code generators you try occasionally” to collaborators that can participate in the development workflow. This article uses Claude Code as an example to explain what needs to be decided before daily use. The examples are based on common usage in Claude Code’s public documentation; features and interfaces change between versions. Before you start, run claude --version to record the version, and consult the official Claude Code documentation for current behavior.
1. Understand the Agent’s Behavioral Boundaries
Unlike ordinary code completion, an agent reasons through multiple steps toward a goal: it reads project files, proposes changes, executes commands, runs tests, and adjusts based on the results. Users need to watch three control points.
- Session control: when to start a new session, and when to clean up or compact context.
- Permission control: which files the agent can read and write, and which commands it can execute.
- Validation control: whether changes are automatically checked, and whether failed checks block subsequent actions.
Once these three points are clear, moving on to specific commands and configuration can significantly reduce situations that “look automated but are actually out of control.”
2. Choose Authentication and Billing
Claude Code commonly supports two access methods. The first is to log in with a Claude subscription account: start claude and run /login. The second is to use a Claude Console API key billed by usage, injected through the ANTHROPIC_API_KEY environment variable. The differences are as follows.
| Dimension | Subscription plan | Pay-as-you-go API key |
|---|---|---|
| Suitable scenario | Frequent daily use, individual developers | Unstable call volume, settlement based on actual consumption |
| Cost predictability | Higher, fixed monthly fee | Fluctuates with usage; set usage alerts |
| Team audit | Individual accounts are hard to audit uniformly | Usage can be separated by key in the console |
| Key management | Login state is stored on the local machine | Keys need to be separated by development, test, and production environments |
Plan tiers, limits, and prices change frequently. Use the official pricing page and contract for specific numbers.
When choosing, ask yourself four questions: Is call frequency stable? Do you need team-level permissions and auditing? Should development, test, and production use separate keys? How much does model choice affect cost?
There are three security baselines. First, do not share personal accounts and keys within a team; sharing makes usage and actions impossible to trace. Second, do not write keys into settings.json or CLAUDE.md, and do not commit them to version control. Inject them through shell environment variables or a secrets management service. Third, enterprise environments should use the management capabilities of Team or Enterprise editions, together with usage alerts and least privilege.
3. Common Slash Commands
Type / in the Claude Code interactive interface to see the command list. These are the most commonly used commands in daily work.
/help View the command list and usage/clear Clear the current session history; useful when switching to an unrelated task/compact Compact the conversation history; can include instructions, e.g. /compact keep the interface contract and test commands/config View or modify configuration/memory Open and edit the project memory file (CLAUDE.md)/rewind Select a checkpoint and restore code, conversation, or both
The core of session management is context hygiene. Use /clear when switching tasks. When the context is very long and the agent starts repeating the same mistakes, use /compact and specify what to keep. When compacting, preserve goals, constraints, and confirmed conclusions. The compacted summary cannot replace code and documentation.
There are three common mistakes. First, making large changes and running /clear without creating a checkpoint, then being unable to return to the previous state. Second, compacting without saying what to retain, so key constraints are lost and the agent later violates agreements. Third, leaving key decisions only in the conversation, so they disappear after starting a new session. Key decisions should be written into CLAUDE.md.
4. Layered Configuration for Consistent Team Behavior
Claude Code configuration has three layers.
- User level:
~/.claude/settings.json, for personal preferences that apply to all projects. - Project shared level:
.claude/settings.jsonin the project root, committed to version control and shared by the team. - Project personal level:
.claude/settings.local.json, for personal overrides in this project, and should be added to.gitignore.
A team-shared permission configuration can look like this:
{"permissions": {"allow": ["Bash(npm run test)","Bash(npm run lint)"],"deny": ["Read(./.env)","Read(./secrets/**)","Bash(rm -rf:*)"]}}
allow lists commands that can run without confirmation, and deny lists paths that must not be read and commands that must not be executed. These correspond to “command categories allowed to execute” and “paths forbidden to access.” Tighten the scope according to the project’s actual situation; do not open everything at the start.
There are three configuration design principles. First, prioritize project-shared configuration to ensure consistent team behavior. Second, sensitive information must not enter any configuration file. Third, configuration changes should be reviewed like code changes.
5. Run Inside the IDE
Claude Code provides extensions for editors such as VS Code, and it can also run claude directly in the integrated terminal. Viewing diffs, running tests, and deciding whether to roll back in the same window minimizes context switching.
Operational boundaries still need to be set. The agent should not have full terminal permissions by default. Operations such as deleting files, modifying dependencies, running deployment scripts, and accessing external networks should go through confirmation steps via permissions or hooks. Teams should standardize IDE integration and project configuration to avoid inconsistent behavior caused by differences in individual environments.
6. Hooks: Make Validation Enforced
Hooks execute scripts before or after specific events in the agent lifecycle. PreToolUse fires before a tool call, and PostToolUse fires after a tool call. When a PreToolUse script exits with code 2, Claude Code blocks the call and feeds the script’s stderr back to the agent.
The following configuration attaches an interception script to all Bash calls and is written in .claude/settings.json:
{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block_dangerous.sh"}]}]}}
The script file .claude/hooks/block_dangerous.sh is as follows. Before use, run chmod +x and install jq.
#!/usr/bin/env bashset -euo pipefail# Claude Code passes JSON via stdininput=$(cat)cmd=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')if printf '%s' "$cmd" | grep -qE 'rm -rf|git push .*--force|DROP TABLE'; thenecho "Blocked dangerous command: $cmd" >&2exit 2fiexit 0
The script can be verified offline without waiting for the agent to trigger it. Run the following command; the output should be 2:
echo '{"tool_input":{"command":"rm -rf build"}}' | .claude/hooks/block_dangerous.sh; echo $?
Avoid three pitfalls when designing hooks. First, running a long full test suite after every edit makes feedback very slow. Second, if hook failures only warn and do not block, the rule is effectively useless. Third, hook scripts have no version control or tests. PostToolUse can only provide feedback after a change has occurred and cannot undo files that have already been written, so fast formatting and lightweight static checks are suitable here. Blocking rules should go in PreToolUse. Hook scripts should be committed with the code and reviewed like other scripts.
7. Project Memory: Capture Conventions in CLAUDE.md
Claude Code reads CLAUDE.md at startup. The CLAUDE.md in the project root is project-level memory, committed to version control and shared by the team. User-level memory is located at ~/.claude/CLAUDE.md and should contain only personal preferences. Run /memory in the interactive interface to open and edit these files.
Here is an example:
# Project Memory## Project goals and boundaries- Order service; code lives in services/order.- Do not modify any files under services/payment.## Build and test- Install dependencies: pnpm install- Unit tests: pnpm test:unit. Must run and pass after interface changes.- Static checks: pnpm lint. Must pass before commit.## Code conventions- API responses must use ok() and fail() from src/common/response.ts.- New database fields require a migration file. Do not modify migrations that have already been released.## Security restrictions- Do not read .env or the secrets/ directory.- Database changes: generate migration files only; do not execute DROP or TRUNCATE directly.## Common issues- Local Redis connection failure: run docker compose up -d redis first.- Intermittent test timeout: rerun with pnpm test:unit -- --runInBand.
Memory content should be concise, executable, and verifiable. A description such as “pay attention to code quality” cannot be checked, while “run pnpm test:unit and pass after interface changes” can be verified. Do not write temporary tasks, one-off debugging information, or credentials into memory. The longer the memory, the more key constraints are diluted, so review it monthly and remove deprecated interface notes, expired temporary commands, and temporary workarounds for already-fixed issues. Changes to memory files should be reviewed together with code changes.
8. Checkpoints and Rollback for Long Workflows
An agent may modify multiple files and execute multiple commands in succession. Checkpoints and rollback are the safety net for long workflows. In Claude Code, run /rewind to select a checkpoint and restore code, conversation, or both.
There are two boundaries to clarify about checkpoints. First, checkpoints mainly cover file modifications made by the agent through editing tools. Operations executed through Bash, such as mv, rm, and package manager installs, may not be included in checkpoint records. Second, side effects such as database migrations, message sending, deployments, third-party write API calls, and cloud resource deletion cannot be undone by local rollback.
Therefore, local rollback cannot be treated as a universal recovery method and should be used with Git. Before large refactors, dependency upgrades, or batch changes, commit the current state or switch to a new branch:
git add -A && git commit -m "checkpoint: baseline before refactor"git switch -c refactor/order-api
For operations involving irreversible side effects, handle them in three steps before execution. First, do a dry run, for example generating SQL without executing it. Second, make a backup, such as a database snapshot. Finally, require human approval before executing the actual change.
Workflow rules can be simplified into four points: make small changes and run validation at each step; proceed to the next step only after validation passes; when validation fails, roll back first and then analyze the cause; for operations involving external side effects, back up and obtain confirmation first. Rollback is a way to keep trial-and-error costs acceptable; it is not a synonym for failure.
9. Reusable Workflows: Custom Commands and Skills
Claude Code provides two reusable mechanisms, suitable for packaging repetitive tasks with clear steps.
The first is custom slash commands. Place a Markdown file under .claude/commands/; the file name becomes the command name. For example, .claude/commands/new-api.md corresponds to /new-api. $ARGUMENTS in the file is replaced with the arguments after the command. Project-level commands go in the project’s .claude/commands/, and personal commands go in ~/.claude/commands/.
Add a new API endpoint to services/order with arguments: $ARGUMENTSSteps:1. Add a route in src/routes and call ok() and fail() from src/common/response.ts.2. Add corresponding unit tests under tests/unit.3. Run pnpm test:unit and pnpm lint; finish only after both pass.4. Do not modify services/payment and do not read .env.
The second is Agent Skills. Write the skill instructions in .claude/skills/<skill-name>/SKILL.md, with name and description in the file header. Claude uses the description to decide when to invoke the skill, so the description should clearly state applicable and non-applicable scenarios. When a skill involves writing files or executing commands, state permission requirements in the instructions and reuse project-level hooks and validation.
When designing a skill, clarify four things: input parameters, scope, execution steps, and failure handling. Skill names should be semantic, and one skill should handle only one type of task. Project-level skills serve team conventions, while user-level skills serve personal habits. Skills should not hide dangerous operations; all writes and external calls should be covered by checkpoints, hooks, or logs.
10. Rollout Advice: Start with One Minimal Closed Loop
Proceed in the following order rather than launching everything at once.
- Trial with a personal subscription or a small pay-as-you-go key for two weeks, and record common commands and session management habits.
- Create a shared
.claude/settings.jsonandCLAUDE.mdfor the project, codifying testing, formatting, and security rules. - Introduce a small number of high-value hooks, prioritizing dangerous command blocking and quick validation after changes.
- Package high-frequency flows as custom commands or skills, and agree on which operations require a checkpoint first.
When evaluating, focus on change reviewability, validation pass rate, rollback count, and manual confirmation count. Lines of generated code do not represent effectiveness. Once these metrics are stable, agentic coding tools will move from novelty to a reusable, governable development capability.
