IAM (Identity and Access Management)¶
IAM (Identity and Access Management) is a service that allows you to manage access control to your Google Cloud resources. The IdentityAccessManager
and IAMCredentials
classes in gcp-pilot provide high-level interfaces for interacting with Google Cloud IAM.
Installation¶
To use the IAM functionality, you need to install gcp-pilot with the iam extra:
pip install gcp-pilot[iam]
Usage¶
IdentityAccessManager¶
The IdentityAccessManager
class allows you to manage service accounts and their keys, as well as IAM policies.
Initialization¶
from gcp_pilot.iam import IdentityAccessManager
# Initialize with default credentials
iam = IdentityAccessManager()
# Initialize with specific project
iam = IdentityAccessManager(project_id="my-project")
# Initialize with service account impersonation
iam = IdentityAccessManager(impersonate_account="service-account@project-id.iam.gserviceaccount.com")
Managing Service Accounts¶
# Create a service account
service_account = iam.create_service_account(
name="my-service-account",
display_name="My Service Account",
project_id="my-project", # Optional: defaults to the project associated with credentials
exists_ok=True, # Optional: if True, returns the existing service account if it already exists
)
print(f"Service Account: {service_account['email']}")
# Get a service account
service_account = iam.get_service_account(
name="my-service-account",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Service Account: {service_account['email']}")
# List all service accounts in a project
service_accounts = iam.list_service_accounts(
project_id="my-project", # Optional: defaults to the project associated with credentials
)
for account in service_accounts:
print(f"Service Account: {account['email']}")
Managing Service Account Keys¶
# Create a key for a service account
key = iam.create_key(
service_account_name="my-service-account",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Key ID: {key['id']}")
print(f"Private Key JSON: {key['json']}")
# List keys for a service account
keys = iam.list_keys(
service_account_name="my-service-account",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
for key in keys:
print(f"Key ID: {key['id']}")
print(f"Valid After: {key['validAfterTime']}")
print(f"Valid Before: {key['validBeforeTime']}")
# Get a specific key
key = iam.get_key(
key_id="key-id",
service_account_name="my-service-account",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Key ID: {key['id']}")
print(f"Valid After: {key['validAfterTime']}")
print(f"Valid Before: {key['validBeforeTime']}")
# Delete a key
iam.delete_key(
key_id="key-id",
service_account_name="my-service-account",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
Managing IAM Policies¶
# Get the IAM policy for a service account
policy = iam.get_policy(
email="my-service-account@my-project.iam.gserviceaccount.com",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Policy: {policy}")
# Bind a member to a role for a service account
policy = iam.bind_member(
target_email="my-service-account@my-project.iam.gserviceaccount.com",
member_email="user@example.com",
role="roles/iam.serviceAccountUser",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Updated Policy: {policy}")
# Remove a member from a role for a service account
policy = iam.remove_member(
target_email="my-service-account@my-project.iam.gserviceaccount.com",
member_email="user@example.com",
role="roles/iam.serviceAccountUser",
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Updated Policy: {policy}")
# Set a custom policy for a service account
policy = iam.set_policy(
email="my-service-account@my-project.iam.gserviceaccount.com",
policy=custom_policy, # A policy object
project_id="my-project", # Optional: defaults to the project associated with credentials
)
print(f"Updated Policy: {policy}")
IAMCredentials¶
The IAMCredentials
class allows you to work with IAM credentials, including JWT tokens, ID tokens, and custom tokens.
Initialization¶
from gcp_pilot.iam import IAMCredentials
# Initialize with default credentials
iam_credentials = IAMCredentials()
# Initialize with service account impersonation
iam_credentials = IAMCredentials(impersonate_account="service-account@project-id.iam.gserviceaccount.com")
Working with JWT Tokens¶
# Encode a JWT token
payload = {
"sub": "user@example.com",
"aud": "https://example.com",
"iat": datetime.now(tz=UTC).timestamp(),
"exp": (datetime.now(tz=UTC) + timedelta(hours=1)).timestamp(),
"custom_claim": "custom_value",
}
jwt_token = iam_credentials.encode_jwt(
payload=payload,
service_account_email="service-account@project-id.iam.gserviceaccount.com",
)
print(f"JWT Token: {jwt_token}")
# Decode a JWT token
decoded_token = IAMCredentials.decode_jwt(
token=jwt_token,
issuer_email="service-account@project-id.iam.gserviceaccount.com",
audience="https://example.com",
verify=True, # Optional: if True, verifies the token signature
cache_certs=True, # Optional: if True, caches the public certificates
clock_skew_in_seconds=0, # Optional: allows for clock skew
)
print(f"Decoded Token: {decoded_token}")
Working with ID Tokens¶
# Generate an ID token
id_token = iam_credentials.generate_id_token(
audience="https://example.com",
service_account_email="service-account@project-id.iam.gserviceaccount.com", # Optional: defaults to the impersonated account
)
print(f"ID Token: {id_token}")
# Decode an ID token
decoded_token = IAMCredentials.decode_id_token(
token=id_token,
audience="https://example.com", # Optional: if provided, verifies the audience
)
print(f"Decoded Token: {decoded_token}")
Working with Custom Tokens¶
# Generate a custom token for Firebase Authentication
custom_token = iam_credentials.generate_custom_token(
uid="user123", # Optional: defaults to a random UUID
expires_in_seconds=3600, # Optional: defaults to 12 hours
tenant_id="tenant123", # Optional: for multi-tenancy
auth_email="service-account@project-id.iam.gserviceaccount.com", # Optional: defaults to the impersonated account
claims={"premium_account": True}, # Optional: custom claims
)
print(f"Custom Token: {custom_token}")
# Decode a custom token
decoded_token = IAMCredentials.decode_custom_token(
token=custom_token,
issuer_email="service-account@project-id.iam.gserviceaccount.com",
verify=True, # Optional: if True, verifies the token signature
)
print(f"Decoded Token: {decoded_token}")
Error Handling¶
The IAM classes handle common errors and convert them to more specific exceptions:
from gcp_pilot import exceptions
try:
iam.get_service_account(name="non-existent-account")
except exceptions.NotFound:
print("Service account not found")
try:
iam.create_service_account(name="existing-account", display_name="Existing Account", exists_ok=False)
except exceptions.AlreadyExists:
print("Service account already exists")
try:
iam_credentials.encode_jwt(payload={"exp": datetime.now(tz=UTC).timestamp() + 13 * 60 * 60}, service_account_email="service-account@project-id.iam.gserviceaccount.com")
except ValueError:
print("JWT tokens cannot be valid for more than 12 hours")
Working with Service Account Impersonation¶
Service account impersonation allows you to act as a service account without having its key file. This is a more secure approach than downloading and storing service account keys.
# Initialize with service account impersonation
iam = IdentityAccessManager(impersonate_account="service-account@project-id.iam.gserviceaccount.com")
# Now all operations will be performed as the impersonated service account
service_account = iam.get_service_account(name="another-service-account")
For more information on service account impersonation, see the Authentication documentation.
Common IAM Roles¶
Here are some common IAM roles that you might use with service accounts:
roles/iam.serviceAccountUser
: Allows a user to impersonate a service accountroles/iam.serviceAccountTokenCreator
: Allows a user to create tokens for a service accountroles/iam.serviceAccountKeyAdmin
: Allows a user to manage keys for a service accountroles/iam.serviceAccountAdmin
: Allows a user to create and manage service accounts
You can use these roles when binding members to service accounts:
# Grant the serviceAccountUser role to a user
policy = iam.bind_member(
target_email="my-service-account@my-project.iam.gserviceaccount.com",
member_email="user@example.com",
role="roles/iam.serviceAccountUser",
)