Skip to content

Commit a727ccc

Browse files
sushma-m1mboglesby
authored andcommitted
Pull request #48: Feature/secure auth anf gcnv
Merge in SIE-BB/netapp-dataops-toolkit from feature/secure-auth-anf-gcnv to release-v3.1.0 * commit '3da1488775aefe1e801ff7f88fc4dd6cc76a25c8': NSOL-6266: fixing path manipulation vulnerability from coverity scan NSOL-6228: updating documentation NSOL-6228: updating anf mcp server documentation NSOL-6228: updating authentication process in anf documentation
2 parents d6cf100 + 3da1488 commit a727ccc

3 files changed

Lines changed: 68 additions & 61 deletions

File tree

netapp_dataops_traditional/docs/anf_mcp_server_readme.md

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -47,45 +47,44 @@ After installation, the `netapp_dataops_anf_mcp.py` command will be available in
4747

4848
### Azure Authentication
4949

50-
The MCP server uses **Azure CLI authentication** (`AzureCliCredential`) and automatically retrieves your subscription ID from the active Azure CLI session.
50+
The MCP server uses **`DefaultAzureCredential`** from `azure-identity`, which automatically selects the appropriate credential based on the environment — no configuration required. The active subscription is resolved via the Azure SDK's `SubscriptionClient`.
51+
52+
> **No secrets or environment variables are required.** The credential resolves automatically based on the environment.
5153
5254
#### Required Setup
5355

54-
1. **Install Azure CLI**: Follow the [installation guide](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli)
56+
Authenticate once via Azure CLI:
5557

56-
2. **Login to Azure**:
57-
```bash
58-
az login
59-
```
58+
```bash
59+
# Install Azure CLI (if not already installed)
60+
# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
6061

61-
3. **If you have access to multiple tenants, specify the tenant ID**:
62-
```bash
63-
az login --tenant <TENANT-ID>
64-
```
62+
# Login to Azure (opens browser)
63+
az login
6564

66-
4. **If you have multiple subscriptions, set the active one**:
67-
```bash
68-
az account set --subscription <SUBSCRIPTION_ID>
69-
```
65+
# If you have access to multiple tenants, specify the tenant ID
66+
az login --tenant <TENANT_ID>
7067

71-
5. **Verify your active subscription**:
72-
```bash
73-
az account show
74-
```
68+
# If you have multiple subscriptions, set the active one
69+
az account set --subscription <SUBSCRIPTION_ID>
70+
71+
# Verify active session (optional – subscription is auto-detected via the SDK)
72+
az account show
73+
```
7574

76-
#### How It Works
7775

78-
- The MCP server automatically runs `az account show` to detect your active subscription
79-
- Subscription ID is retrieved dynamically on each operation
80-
- Respects your Azure CLI tenant and subscription context
81-
- No need to configure or store subscription ID in config files or environment variables
76+
**How It Works:**
77+
- `DefaultAzureCredential` is instantiated and passed to `SubscriptionClient`
78+
- The first available subscription is resolved via the Azure SDK
79+
- The resolved `subscription_id` is used to initialize `NetAppManagementClient`
80+
- The client is cached in a singleton (`ANFClientManager`) and reused across calls
8281

83-
#### Benefits
82+
**Benefits:**
83+
- **Zero secrets** – No `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, or `AZURE_TENANT_ID` needed
84+
- **Portable** – Works in local dev, CI/CD, containers, and Azure-hosted environments
85+
- **Subscription auto-resolved** – No subscription ID in config files or function parameters
86+
- **Multi-tenant support** – Respects `az login --tenant`
8487

85-
- **Simplified Setup**: No subscription ID in config files or function parameters
86-
- **Better Security**: Subscription ID not stored anywhere
87-
- **Multi-Tenant Support**: Easy switching between tenants/subscriptions with Azure CLI
88-
- **Automatic Detection**: Works seamlessly with your Azure CLI context
8988

9089
### ANF Configuration (Optional)
9190

@@ -130,7 +129,7 @@ The configuration file is stored at `~/.netapp_dataops/anf_config.json` and cont
130129
}
131130
```
132131

133-
> **📝 Note:** The subscription ID is **not** stored in the configuration file. It is automatically retrieved from your active Azure CLI session using `az account show`.
132+
> **📝 Note:** The subscription ID is **not** stored in the configuration file. It is automatically resolved at runtime via `DefaultAzureCredential` and the Azure SDK's `SubscriptionClient`.
134133
135134
#### Configuration Benefits and Usage
136135

@@ -281,7 +280,9 @@ Set up disaster recovery:
281280
1. **Authentication Failed**:
282281
```bash
283282
az login
284-
# or check service principal credentials
283+
# or for a specific tenant
284+
az login --tenant <TENANT_ID>
285+
# verify active session
285286
az account show
286287
```
287288

@@ -379,7 +380,6 @@ print('Config test - Account:', get_config_value('account_name'))
379380
- Regularly review and update Azure role assignments
380381
- Implement proper network security groups and access controls
381382
- Enable encryption at rest and in transit where required
382-
- Use Azure managed identities for production workloads where possible
383383
- Leverage Azure Active Directory for centralized authentication
384384

385385
## Support

netapp_dataops_traditional/docs/anf_readme.md

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Built on the [Azure NetApp Files Python SDK](https://docs.microsoft.com/en-us/py
1818
- [Prerequisites](#prerequisites)
1919
- [Installation Instructions](#installation-instructions)
2020
- [Authentication](#authentication)
21-
- [Azure CLI Authentication (Required)](#azure-cli-authentication-required)
21+
- [Authentication Methods (DefaultAzureCredential)](#authentication-methods-defaultazurecredential)
2222
- [Configuration](#configuration)
2323
- [Option 1: Interactive Configuration (Recommended)](#option-1-interactive-configuration-recommended)
2424
- [Option 2: Manual Configuration](#option-2-manual-configuration)
@@ -104,44 +104,50 @@ python3 -m pip install 'netapp-dataops-traditional[azure]'
104104

105105
## Authentication
106106

107-
The ANF module uses **Azure CLI authentication** (`AzureCliCredential`) and automatically retrieves your subscription ID from the active Azure CLI session.
107+
The ANF module uses **`DefaultAzureCredential`** from `azure-identity`, which automatically chains through multiple authentication methods without requiring any environment variables or secrets. The active subscription is resolved via the Azure SDK's `SubscriptionClient`.
108108

109-
<a name="option-1-azure-cli-recommended"></a>
109+
<a name="authentication-methods-defaultazurecredential"></a>
110110

111-
### Azure CLI Authentication (Required)
111+
### Authentication Methods (DefaultAzureCredential)
112+
113+
`DefaultAzureCredential` automatically selects the appropriate credential based on the environment — no configuration required.
114+
115+
> **No secrets or environment variables are required.** The credential resolves automatically based on the environment.
116+
117+
#### Required Setup
118+
119+
Authenticate once via Azure CLI:
112120

113-
**Required Setup:**
114121
```bash
115122
# Install Azure CLI (if not already installed)
116123
# https://docs.microsoft.com/en-us/cli/azure/install-azure-cli
117124

118-
# Login to Azure
125+
# Login to Azure (opens browser)
119126
az login
120127

121128
# If you have access to multiple tenants, specify the tenant ID
122-
az login --tenant <TENANT-ID>
129+
az login --tenant <TENANT_ID>
123130

124131
# If you have multiple subscriptions, set the active one
125132
az account set --subscription <SUBSCRIPTION_ID>
126133

127-
# Verify your active subscription
134+
# Verify active session (optional – subscription is auto-detected via the SDK)
128135
az account show
129136
```
130137

138+
131139
**How It Works:**
132-
- The toolkit automatically runs `az account show` to detect your active subscription
133-
- Subscription ID is retrieved dynamically on each operation
134-
- Respects your Azure CLI tenant and subscription context
135-
- No need to configure or store subscription ID in config files or environment variables
140+
- `DefaultAzureCredential` is instantiated and passed to `SubscriptionClient`
141+
- The first available subscription is resolved via the Azure SDK
142+
- The resolved `subscription_id` is used to initialize `NetAppManagementClient`
143+
- The client is cached in a singleton (`ANFClientManager`) and reused across calls
136144

137145
**Benefits:**
138-
-**Simplified Setup**: No subscription ID in config files or function parameters
139-
-**Better Security**: Subscription ID not stored anywhere
140-
-**Multi-tenant Support**: Automatically respects `az login --tenant`
141-
-**Multi-subscription Support**: Honors `az account set --subscription`
142-
-**Consistent Authentication**: Uses same credentials as Azure CLI
143-
144-
**Note:** Service Principal and environment variable authentication methods are no longer supported. The module now exclusively uses Azure CLI authentication for consistency and security.
146+
- **Zero secrets** – No `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, or `AZURE_TENANT_ID` needed
147+
- **Portable** – Works in local dev, CI/CD, containers, and Azure-hosted environments
148+
- **Subscription auto-resolved** – No subscription ID in config files or function parameters
149+
- **Multi-tenant support** – Respects `az login --tenant`
150+
- **Production-ready** – Managed Identity support means no credential rotation required
145151

146152
## Configuration
147153

@@ -184,10 +190,10 @@ python3 -c "from netapp_dataops.traditional.anf.config import create_anf_config;
184190
**Note:** Subscription ID is NOT needed - it's automatically detected from your Azure CLI session.
185191

186192
**Benefits:**
187-
- **Simplified function calls** - Pass only unique parameters
188-
- 🎯 **Consistent defaults** - Reuse infrastructure settings across operations
189-
- 🛡️ **Reduced errors** - Pre-validated configuration values
190-
- 📝 **Version control friendly** - Config file can be shared across teams
193+
- **Simplified function calls** - Pass only unique parameters
194+
- **Consistent defaults** - Reuse infrastructure settings across operations
195+
- **Reduced errors** - Pre-validated configuration values
196+
- **Version control friendly** - Config file can be shared across teams
191197

192198
### Configuration File Location
193199

@@ -209,7 +215,7 @@ The configuration is automatically saved to:
209215
}
210216
```
211217

212-
**Note:** Subscription ID is not stored in the config file. It's automatically retrieved from your Azure CLI session via `az account show`.
218+
**Note:** Subscription ID is not stored in the config file. It's automatically resolved at runtime via `DefaultAzureCredential` and the Azure SDK's `SubscriptionClient`.
213219

214220
### Usage with Configuration
215221

@@ -1338,7 +1344,7 @@ czr_result = anf.create_replication(
13381344
Report any issues via GitHub: https://github.com/NetApp/netapp-data-science-toolkit/issues.
13391345
13401346
**Common Issues:**
1341-
- **Authentication failures**: Ensure Azure CLI is logged in or service principal credentials are correct
1347+
- **Authentication failures**: Ensure `az login` has been run for local development, or a Managed Identity is assigned in production
13421348
- **Permission denied**: Verify NetApp Contributor role is assigned to your account/service principal
13431349
- **Resource not found**: Check that NetApp Account, Capacity Pool, and delegated subnet exist
13441350
- **Region limitations**: Verify Azure NetApp Files is available in your target region

netapp_dataops_traditional/netapp_dataops/traditional/gcnv/setup_gcnv_auth.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,13 @@ def setup_gcnv_auth() -> None:
9898

9999
# Step 4: Application Default Credentials
100100
print("\nStep 4/8 Application Default Credentials (browser will open)...")
101-
run(['gcloud', 'auth', 'application-default', 'login'], capture=True)
102-
cloudsdk_config = os.environ.get("CLOUDSDK_CONFIG", os.path.expanduser("~/.config/gcloud"))
103-
adc_file = os.path.join(cloudsdk_config, "application_default_credentials.json")
104-
if os.path.exists(adc_file):
101+
run(['gcloud', 'auth', 'application-default', 'login'])
102+
adc_file = os.path.realpath(os.path.expanduser("~/.config/gcloud/application_default_credentials.json"))
103+
if os.path.isfile(adc_file):
105104
os.chmod(adc_file, 0o600)
106-
print("ADC configured and credentials secured (chmod 600)")
105+
print("ADC configured and credentials secured (chmod 600)")
106+
else:
107+
print("ADC file not found; skipping chmod.")
107108

108109
# Step 5: Create service account
109110
print("\nStep 5/8 Create service account...")

0 commit comments

Comments
 (0)