Skip to content

Commit 7c2219c

Browse files
authored
security: remove GRN_CLIENT_ID/SECRET env var support (#9)
2 parents 2635a2a + bf51534 commit 7c2219c

7 files changed

Lines changed: 9 additions & 33 deletions

File tree

CLAUDE.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,14 @@ python -m pytest tests/ -v
7676

7777
2. **CHANGELOG**: Add changelog fragment via `./scripts/new-change`
7878

79-
3. **Spec** (`docs/superpowers/specs/2026-04-10-greenode-cli-design.md`):
80-
- Update command list in Section 4
81-
- Update file structure in Section 2 if new files added
79+
3. **README.md**: Update if installation, configuration, or basic commands change
8280

83-
This is not optional. Code without docs is not done.
81+
4. **CLAUDE.md**: Update if conventions, security rules, or key files change
82+
83+
**After ANY change to business logic, security, configuration, or commands:**
84+
Review ALL docs above and update what's affected. If unsure whether a doc needs updating, read it and check.
85+
86+
Code without docs is not done.
8487

8588
## Key files
8689

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ Default output format [json]:
5959

6060
Credentials are obtained from the [VNG Cloud IAM Portal](https://hcm-3.console.vngcloud.vn/iam/) under Service Accounts.
6161

62-
You can also configure credentials via environment variables:
62+
You can also configure the region via environment variable:
6363

6464
```bash
65-
export GRN_CLIENT_ID=<your-client-id>
66-
export GRN_CLIENT_SECRET=<your-client-secret>
6765
export GRN_DEFAULT_REGION=HCM-3
6866
```
6967

docs/configuration.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ grn vks list-clusters
8484

8585
| Variable | Description |
8686
|----------|-------------|
87-
| `GRN_CLIENT_ID` | Client ID (overrides config file) |
88-
| `GRN_CLIENT_SECRET` | Client Secret (overrides config file) |
8987
| `GRN_DEFAULT_REGION` | Default region |
9088
| `GRN_PROFILE` | Profile name |
9189
| `GRN_DEFAULT_OUTPUT` | Output format |

grncli/customizations/configure/list.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,6 @@ def _resolve_profile(self, profile):
4545
return ('profile', '<not set>', 'None', 'None')
4646

4747
def _resolve_credential(self, key):
48-
env_map = {'client_id': 'GRN_CLIENT_ID', 'client_secret': 'GRN_CLIENT_SECRET'}
49-
env_var = env_map.get(key, '')
50-
env_val = os.environ.get(env_var)
51-
if env_val:
52-
return (key, self._mask_value(env_val), 'env', env_var)
5348
try:
5449
creds = self._session.get_credentials()
5550
value = creds.get(key)

grncli/session.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ class Session:
3131
"""Manages config, credentials, region, and service endpoints.
3232
3333
Credential resolution order (high → low priority):
34-
1. Environment variables: GRN_CLIENT_ID, GRN_CLIENT_SECRET
35-
2. Profile in ~/.greenode/credentials
34+
1. Profile in ~/.greenode/credentials
3635
"""
3736

3837
def __init__(
@@ -98,11 +97,6 @@ def emit_first_non_none(self, event_name: str, **kwargs) -> Any:
9897
return self._emitter.emit_first_non_none(event_name, **kwargs)
9998

10099
def get_credentials(self) -> dict[str, str]:
101-
env_id = os.environ.get('GRN_CLIENT_ID')
102-
env_secret = os.environ.get('GRN_CLIENT_SECRET')
103-
if env_id and env_secret:
104-
return {'client_id': env_id, 'client_secret': env_secret}
105-
106100
if self._credentials_cache is not None:
107101
return self._credentials_cache
108102

tests/functional/test_cli_integration.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ def greenode_config(tmp_path):
2424
config.write_text("[default]\nregion = HCM-3\noutput = json\n")
2525

2626
with patch.dict(os.environ, {}, clear=False):
27-
os.environ.pop('GRN_CLIENT_ID', None)
28-
os.environ.pop('GRN_CLIENT_SECRET', None)
2927
os.environ.pop('GRN_DEFAULT_REGION', None)
3028
os.environ.pop('GRN_PROFILE', None)
3129

tests/unit/test_session.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,6 @@ def test_load_profile_credentials(self, config_dir):
4949
assert creds['client_id'] == 'staging-id'
5050
assert creds['client_secret'] == 'staging-secret'
5151

52-
def test_env_vars_override_file(self, config_dir):
53-
with patch.dict(os.environ, {
54-
'GRN_CLIENT_ID': 'env-id',
55-
'GRN_CLIENT_SECRET': 'env-secret',
56-
}):
57-
session = Session(config_dir=str(config_dir))
58-
creds = session.get_credentials()
59-
assert creds['client_id'] == 'env-id'
60-
assert creds['client_secret'] == 'env-secret'
61-
6252
def test_missing_credentials_raises(self, tmp_path):
6353
session = Session(config_dir=str(tmp_path))
6454
with pytest.raises(Exception, match="credentials"):

0 commit comments

Comments
 (0)