Back to Guides
Advanced
60 minutes
Custom RBAC Policies
Master TigerAccess role-based access control. Create sophisticated policies with label selectors, time-based access, and approval workflows.
Overview
TigerAccess RBAC provides fine-grained access control with:
- Label-Based Access: Dynamic resource selection using labels
- Allow/Deny Rules: Explicit permission and restriction policies
- Time Constraints: Temporary access and business hours restrictions
- Approval Workflows: Just-in-time access with peer approval
Prerequisites
- TigerAccess cluster running with auth service
- Admin access (editor role) to create roles
- Resources (nodes, databases, clusters) labeled appropriately
- Understanding of your organization's access requirements
Role Basics
Basic Role Structure
kind: role
version: v7
metadata:
name: example-role
description: "Description of what this role provides"
spec:
# Allow rules - what is permitted
allow:
logins: ["ubuntu", "ec2-user"]
node_labels:
env: ["development", "staging"]
# Deny rules - explicit restrictions (takes precedence)
deny:
node_labels:
team: ["finance"]
# Role options
options:
max_session_ttl: "8h"
require_session_mfa: falseCreate a Role
# Create from spec
tac roles create developer --spec - <<EOF
# ... role spec ...
EOF
# Or from file
tac roles create developer --spec=developer-role.yaml
# Assign to user
tac users update alice --add-role=developerLabel Selectors
SSH Node Labels
allow:
logins: ["ubuntu", "admin"]
# Match multiple label values
node_labels:
env: ["development", "staging"]
region: ["us-east-1", "us-west-2"]
team: ["backend"]
# Wildcard matching
node_labels:
env: "*" # All environments
hostname: "web-*" # Hosts starting with web-
# Regular expressions
node_labels:
env: "^(dev|test).*$"Database Labels
allow:
db_labels:
env: ["development"]
type: ["postgres", "mysql"]
db_names: ["*"] # All databases
db_users: ["readonly", "readwrite"]
deny:
# Explicitly deny production databases
db_labels:
env: ["production"]
# Deny specific databases
db_names: ["sensitive_data", "financial_records"]Kubernetes Labels
allow:
kubernetes_labels:
env: ["staging"]
region: ["us-east-1"]
kubernetes_resources:
# Allow read-only access to all pods
- kind: pod
namespace: "*"
name: "*"
verbs: ["get", "list", "watch"]
# Allow full access to specific namespace
- kind: "*"
namespace: "team-backend"
name: "*"
verbs: ["*"]
kubernetes_groups:
- "view"
- "edit"Time-Based Access
Business Hours Restriction
kind: role
version: v7
metadata:
name: business-hours-access
spec:
allow:
node_labels:
env: ["production"]
options:
# Only allow access during business hours
access_schedule:
timezone: "America/New_York"
windows:
- days: ["monday", "tuesday", "wednesday", "thursday", "friday"]
start_time: "09:00"
end_time: "17:00"On-Call Access
kind: role
version: v7
metadata:
name: on-call-engineer
spec:
allow:
node_labels:
env: ["production"]
options:
# 24/7 access for on-call
max_session_ttl: "4h"
# But requires MFA
require_session_mfa: true
# Auto-revoke after 7 days
max_connections: 100
cert_ttl: "168h"Temporary Access
# Grant temporary access to user
tac users update alice --add-role=prod-access --ttl=8h
# Or create a temporary role assignment
tac access-list create contractor-access --spec - <<EOF
kind: access_list
version: v1
metadata:
name: contractor-access
spec:
members:
- "contractor@example.com"
grants:
roles: ["developer"]
expires: "2024-12-31T23:59:59Z"
EOFAccess Request Workflow
Requestable Role
kind: role
version: v7
metadata:
name: prod-access-request
spec:
allow:
node_labels:
env: ["production"]
logins: ["ubuntu"]
request:
# Users can request this role
roles: ["prod-access"]
# Require specific reason
claims_to_roles:
- claim: "reason"
value: "*incident*"
options:
# Require approval
require_session_mfa: true
# Max request duration
max_session_ttl: "2h"Approval Plugin
kind: role
version: v7
metadata:
name: approver
spec:
allow:
# Can approve requests for prod-access
review_requests:
roles: ["prod-access"]
# Slack integration for approvals
plugins:
- name: slack
settings:
webhook_url: "https://hooks.slack.com/..."
channel: "#access-requests"Request Access
# User requests access
tac request create --roles=prod-access \
--reason="Incident INC-123: investigating database performance" \
--duration=2h
# Approver reviews
tac requests ls
tac requests approve REQUEST_ID
# Or deny
tac requests deny REQUEST_ID --reason="Need more details"Advanced Patterns
Trait-Based Access
# Use user traits for dynamic access
allow:
node_labels:
# Access based on user's team trait
team: "{{internal.user_traits.team}}"
# Access based on user's department
department: "{{external.department}}"
logins:
# Username derived from email
- "{{internal.user_traits.username}}"
- "{{external.preferred_username}}"Multi-Tier Access
# Junior Developer - Limited access
kind: role
metadata:
name: junior-dev
spec:
allow:
node_labels:
env: ["development"]
logins: ["deploy"]
deny:
node_labels:
critical: ["true"]
---
# Senior Developer - More access
kind: role
metadata:
name: senior-dev
spec:
allow:
node_labels:
env: ["development", "staging"]
logins: ["deploy", "admin"]
options:
# Can request production access
request:
roles: ["prod-access"]
---
# Principal Engineer - Full access
kind: role
metadata:
name: principal-engineer
spec:
allow:
node_labels:
env: "*"
logins: ["root", "admin"]
options:
max_session_ttl: "12h"Break-Glass Access
kind: role
metadata:
name: emergency-access
spec:
allow:
node_labels:
"*": "*" # All resources
logins: ["root"]
options:
# Very short TTL
max_session_ttl: "1h"
# Always requires MFA
require_session_mfa: true
# Record everything
record_session:
desktop: true
default: "yes"
# Send alerts
notify:
- type: "slack"
webhook: "https://hooks.slack.com/..."
- type: "email"
recipients: ["security@example.com"]Best Practices
Do's
- ✓ Use label-based selectors instead of hardcoded resource names
- ✓ Apply principle of least privilege - start restrictive, expand as needed
- ✓ Require MFA for production and sensitive resource access
- ✓ Set appropriate session TTLs (shorter for production)
- ✓ Use deny rules to explicitly block sensitive resources
- ✓ Document role purpose in metadata description
- ✓ Use access requests for elevated/temporary access
- ✓ Regular audit of role assignments and usage
Don'ts
- ✗ Grant wildcard access ("*") unless absolutely necessary
- ✗ Create per-user roles - use label selectors instead
- ✗ Skip MFA requirements for production access
- ✗ Set overly long session TTLs (max 12h recommended)
- ✗ Mix development and production access in same role
- ✗ Create roles without deny rules for sensitive resources
- ✗ Grant root/admin logins without clear justification
Real-World Policy Examples
DevOps Engineer
kind: role
version: v7
metadata:
name: devops-engineer
description: "Full access to dev/staging, read-only prod"
spec:
allow:
# Full SSH access to non-prod
node_labels:
env: ["development", "staging"]
logins: ["ubuntu", "deploy", "admin"]
# Database access
db_labels:
env: ["development", "staging"]
db_users: ["admin"]
# Kubernetes access
kubernetes_labels:
env: ["development", "staging"]
kubernetes_groups: ["edit"]
# Read-only production
allow:
node_labels:
env: ["production"]
logins: ["readonly"]
deny:
# Block PCI databases
db_labels:
compliance: ["pci"]
options:
max_session_ttl: "8h"
record_session:
default: "yes"Database Administrator
kind: role
version: v7
metadata:
name: dba
description: "Database administrator with full DB access"
spec:
allow:
# All database access
db_labels:
"*": "*"
db_users: ["admin", "root", "postgres"]
# SSH to database servers only
node_labels:
role: ["database"]
logins: ["postgres", "mysql"]
deny:
# No access to application servers
node_labels:
role: ["web", "api"]
options:
# Require MFA for production
require_session_mfa: true
max_session_ttl: "4h"
# Audit all queries
record_session:
default: "yes"Security Auditor
kind: role
version: v7
metadata:
name: security-auditor
description: "Read-only access for security audits"
spec:
allow:
# Read-only SSH access
node_labels:
"*": "*"
logins: ["auditor", "readonly"]
# View all sessions and audit logs
rules:
- resources: ["session", "event", "audit_log"]
verbs: ["list", "read"]
# Kubernetes read-only
kubernetes_labels:
"*": "*"
kubernetes_groups: ["view"]
deny:
# No write access anywhere
logins: ["root", "admin", "postgres"]
options:
# Long sessions for investigations
max_session_ttl: "12h"
# No MFA required for read-only
require_session_mfa: falseOn This Page
Ready to Secure Your Infrastructure?
Join thousands of security-conscious teams using TigerAccess to protect their critical infrastructure and AI agents.
No credit card required • 14-day free trial • Enterprise support available