n8n-nodes-gcloud-sa-impersonate
Version:
n8n community node for Google Cloud Service Account Token Impersonation
215 lines (162 loc) β’ 6.74 kB
Markdown
# n8n-nodes-gcloud-sa-impersonate
A custom n8n node for impersonating Google Cloud Service Accounts to generate access tokens.
## Features
- π Impersonate Google Cloud Service Accounts without credentials
- π Generate access tokens with configurable lifetime
- βοΈ Configurable GCE metadata server URL
- π― Support for custom scopes and delegation chains
- π³ Docker-based development environment with GCE metadata server emulator
## Installation
### For Development
1. Clone the repository:
```bash
git clone https://github.com/your-username/n8n-nodes-gcloud-sa-impersonate.git
cd n8n-nodes-gcloud-sa-impersonate
```
2. Install dependencies:
```bash
npm install
```
3. Build the node:
```bash
npm run build
```
### Using Docker Compose (Recommended for Testing)
This project includes a complete Docker Compose setup with a GCE metadata server emulator for testing.
#### Prerequisites
1. **Google Cloud Authentication**: Set up Application Default Credentials
```bash
gcloud auth application-default login
```
2. **Service Account Permissions**: Ensure your user account has the following IAM permissions on the target service account:
```bash
# Replace with your email and service account
gcloud iam service-accounts add-iam-policy-binding \
YOUR_SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com \
--member="user:your-email@domain.com" \
--role="roles/iam.serviceAccountTokenCreator"
gcloud iam service-accounts add-iam-policy-binding \
YOUR_SERVICE_ACCOUNT@PROJECT_ID.iam.gserviceaccount.com \
--member="user:your-email@domain.com" \
--role="roles/iam.serviceAccountUser"
```
#### Setup Steps
1. **Set environment variables**:
```bash
# Required: Your Google Cloud Project details
export GOOGLE_PROJECT_ID=your-project-id
export GOOGLE_NUMERIC_PROJECT_ID=123456789012
export GOOGLE_SERVICE_ACCOUNT=your-service-account@your-project-id.iam.gserviceaccount.com
# Required: Access token for GCE metadata server emulator
# Get this value by running: gcloud auth print-access-token
export GOOGLE_ACCESS_TOKEN=$(gcloud auth print-access-token)
```
2. **Create a `.env` file** (optional, for docker-compose):
```bash
# Copy environment variables to .env file for docker-compose
cat << EOF > .env
GOOGLE_PROJECT_ID=${GOOGLE_PROJECT_ID}
GOOGLE_NUMERIC_PROJECT_ID=${GOOGLE_NUMERIC_PROJECT_ID}
GOOGLE_SERVICE_ACCOUNT=${GOOGLE_SERVICE_ACCOUNT}
GOOGLE_ACCESS_TOKEN=${GOOGLE_ACCESS_TOKEN}
EOF
```
3. **Generate metadata server configuration**:
```bash
# This script uses the environment variables above to generate metadata-config/config.json
./bin/gen-config-json.sh
```
4. **Copy your ADC credentials**:
```bash
cp ~/.config/gcloud/application_default_credentials.json ./adc.json
```
#### Running the Stack
1. **Start the services**:
```bash
docker-compose up --build
```
2. **Access n8n**:
- URL: http://localhost:5678
- Username: `admin`
- Password: `admin`
3. **Get fresh access token** (refresh every ~1 hour):
```bash
export GOOGLE_ACCESS_TOKEN=$(gcloud auth print-access-token)
docker-compose up -d
```
## Node Configuration
When creating a workflow in n8n, configure the "Google Cloud SA Impersonate" node with:
| Parameter | Description | Default | Example |
|-----------|-------------|---------|---------|
| **GCE Metadata Server URL** | Metadata server endpoint | `https://metadata.google.internal/` | `http://gce-metadata:8080` (for Docker) |
| **Target Service Account Email** | Service account to impersonate | - | `my-sa@project.iam.gserviceaccount.com` |
| **Scopes** | OAuth 2.0 scopes (comma-separated) | `https://www.googleapis.com/auth/cloud-platform` | `https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/storage` |
| **Delegates** | Delegation chain (optional) | - | `delegate1@project.iam.gserviceaccount.com` |
| **Token Lifetime** | Access token lifetime | `300s` | `3600s`, `1h` |
### Example Node Output
```json
{
"accessToken": "ya29.c.b0Aaekm1....",
"expireTime": "2024-08-07T06:32:18Z",
"targetServiceAccount": "impersonate-test@project.iam.gserviceaccount.com",
"scopes": ["https://www.googleapis.com/auth/cloud-platform"],
"lifetime": "300s"
}
```
## Troubleshooting
### Common Issues
1. **403 Permission Error**:
- Ensure service account impersonation permissions are granted
- Check Organization Policies for impersonation restrictions
- Verify IAM Credentials API is enabled
2. **GCE Metadata Server Connection Failed**:
- For Docker: Use `http://gce-metadata:8080`
- For GCE instances: Use `https://metadata.google.internal/`
- Check container networking and port accessibility
3. **Invalid Access Token**:
- Refresh the `GOOGLE_ACCESS_TOKEN` environment variable
- Ensure ADC credentials (`adc.json`) are up to date
### Debug Commands
```bash
# Test service account impersonation directly
gcloud auth print-access-token --impersonate-service-account=YOUR_SA@PROJECT.iam.gserviceaccount.com
# Check metadata server emulator
curl -H "Metadata-Flavor: Google" http://localhost:8080/computeMetadata/v1/instance/service-accounts/default/token
# View container logs
docker-compose logs gce-metadata
docker-compose logs n8n
```
## Development
### Building the Node
```bash
npm run build
```
### Linting and Formatting
```bash
npm run lint
npm run format
```
### Testing
The Docker Compose setup provides an isolated testing environment with:
- n8n instance with the custom node pre-installed
- GCE metadata server emulator for testing without actual GCE instances
- Persistent data volumes for n8n workflows
## Architecture
```
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β n8n Node βββββΆβ GCE Metadata βββββΆβ Google Cloud β
β β β Server Emulator β β IAM API β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
```
1. **n8n Node** requests access token from metadata server
2. **GCE Metadata Server Emulator** authenticates using your ADC credentials
3. **Google Cloud IAM API** performs service account impersonation
4. Access token is returned through the chain
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request