mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-29 15:40:58 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
---
|
||||
name: None
|
||||
description: Implement Just-In-Time (JIT) access provisioning to eliminate standing privileges by granting temporary, time-bound access only when needed. This skill covers JIT architecture design, approval workflo
|
||||
domain: cybersecurity
|
||||
subdomain: identity-access-management
|
||||
tags: [iam, identity, access-control, jit, provisioning, zero-trust, least-privilege]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
# Implementing Just-In-Time Access Provisioning
|
||||
|
||||
## Overview
|
||||
Implement Just-In-Time (JIT) access provisioning to eliminate standing privileges by granting temporary, time-bound access only when needed. This skill covers JIT architecture design, approval workflows, automatic expiration, integration with PAM and IGA platforms, and alignment with zero trust principles.
|
||||
|
||||
## Objectives
|
||||
- Design JIT access request and approval workflows
|
||||
- Implement time-bound access grants with automatic expiration
|
||||
- Configure risk-based approval routing (auto-approve low-risk, multi-approval for high-risk)
|
||||
- Integrate JIT with PAM for privileged access elevation
|
||||
- Monitor and audit all JIT access grants and usage
|
||||
- Reduce attack surface by eliminating standing privileges
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### JIT Access Models
|
||||
1. **Broker and Remove**: Grant access through approval, auto-remove after time window
|
||||
2. **Elevation on Demand**: User has base access, elevates to privileged upon request
|
||||
3. **Account Creation/Deletion**: Temporary account created, destroyed after use
|
||||
4. **Group Membership Toggle**: Add to privileged group temporarily, auto-remove
|
||||
|
||||
### Zero Standing Privilege (ZSP) Principle
|
||||
- No user has permanent privileged access
|
||||
- All privileged access requires explicit request with business justification
|
||||
- Access automatically expires after defined time window
|
||||
- All access events logged and auditable
|
||||
|
||||
## Implementation Steps
|
||||
|
||||
### Step 1: Identify Eligible Access Types
|
||||
- Privileged admin access (domain admin, root, DBA)
|
||||
- Production environment access
|
||||
- Sensitive data access (PII, financial, healthcare)
|
||||
- Emergency/break-glass access
|
||||
- Third-party vendor access
|
||||
|
||||
### Step 2: Design Approval Workflows
|
||||
- Self-service request portal with justification requirement
|
||||
- Auto-approve for pre-authorized low-risk access (< 1 hour)
|
||||
- Single approver for medium-risk (manager or resource owner)
|
||||
- Dual approval for high-risk (manager + security team)
|
||||
- Emergency bypass with post-facto review
|
||||
|
||||
### Step 3: Implement Time-Bound Access
|
||||
- Configure maximum access duration per resource type
|
||||
- Implement countdown timer with extension request capability
|
||||
- Auto-revoke at expiration regardless of session state
|
||||
- Grace period notification (15 min before expiry)
|
||||
- Automatic session termination on access expiry
|
||||
|
||||
### Step 4: Integration Architecture
|
||||
- Connect to IAM/IGA platform for provisioning/de-provisioning
|
||||
- Integrate with PAM for privileged credential checkout
|
||||
- Connect to ITSM for ticket correlation
|
||||
- Forward events to SIEM for monitoring
|
||||
- API integration for programmatic access requests
|
||||
|
||||
### Step 5: Monitoring and Compliance
|
||||
- Log all JIT requests, approvals, grants, and revocations
|
||||
- Alert on access used beyond approved scope
|
||||
- Track access not used (request but never connected)
|
||||
- Measure mean time to access (request to grant)
|
||||
- Report on access patterns for baseline optimization
|
||||
|
||||
## Security Controls
|
||||
| Control | NIST 800-53 | Description |
|
||||
|---------|-------------|-------------|
|
||||
| Temporary Access | AC-2(2) | Automated temporary account management |
|
||||
| Least Privilege | AC-6 | Time-bound minimum access |
|
||||
| Access Enforcement | AC-3 | Automated access grant/revoke |
|
||||
| Audit | AU-3 | Complete JIT access audit trail |
|
||||
| Risk Assessment | RA-3 | Risk-based approval routing |
|
||||
|
||||
## Common Pitfalls
|
||||
- Setting time windows too long, negating JIT benefits
|
||||
- Not implementing automatic revocation at expiration
|
||||
- Complex approval workflows causing access delays for legitimate needs
|
||||
- Not providing emergency bypass for critical incidents
|
||||
- Failing to audit approved but unused JIT access
|
||||
|
||||
## Verification
|
||||
- [ ] JIT request workflow functional end-to-end
|
||||
- [ ] Access automatically revoked at expiration
|
||||
- [ ] Approval routing correct for all risk levels
|
||||
- [ ] Emergency access bypass works with post-review
|
||||
- [ ] All JIT events logged to SIEM
|
||||
- [ ] Standing privileges reduced by measurable percentage
|
||||
- [ ] Mean time to access meets business SLA
|
||||
@@ -0,0 +1,46 @@
|
||||
# JIT Access Provisioning Policy Template
|
||||
|
||||
## Resource Classification
|
||||
| Resource Type | Risk Level | Max Duration | Auto-Approve | Approvals Required |
|
||||
|---------------|------------|--------------|--------------|-------------------|
|
||||
| Read-only access | Low | 1 hour | Yes | 0 |
|
||||
| Standard application | Medium | 4 hours | No | 1 (manager) |
|
||||
| Production server | High | 4 hours | No | 2 (manager + security) |
|
||||
| Database admin | Critical | 2 hours | No | 2 (DBA lead + security) |
|
||||
| Domain admin | Critical | 1 hour | No | 2 (security + CISO) |
|
||||
| Cloud admin | Critical | 2 hours | No | 2 (cloud team + security) |
|
||||
|
||||
## Approval Workflow Matrix
|
||||
| Risk Level | Standard Request | Emergency Request |
|
||||
|------------|-----------------|-------------------|
|
||||
| Low | Auto-approve | Auto-approve |
|
||||
| Medium | 1 approval | Auto-approve + post-review |
|
||||
| High | 2 approvals | Immediate grant + post-review |
|
||||
| Critical | 2 approvals + MFA | Immediate grant + incident review |
|
||||
|
||||
## Request Form Fields
|
||||
- Requester name and ID
|
||||
- Target resource/system
|
||||
- Access level requested
|
||||
- Duration requested (within policy maximum)
|
||||
- Business justification
|
||||
- Related ticket/incident number
|
||||
- Emergency flag (yes/no)
|
||||
|
||||
## SLA Targets
|
||||
| Metric | Target |
|
||||
|--------|--------|
|
||||
| Mean time to access (low risk) | < 1 minute |
|
||||
| Mean time to access (medium risk) | < 15 minutes |
|
||||
| Mean time to access (high risk) | < 30 minutes |
|
||||
| Emergency access grant | < 2 minutes |
|
||||
| Access revocation at expiry | Immediate (< 1 minute) |
|
||||
| Post-emergency review | Within 24 hours |
|
||||
|
||||
## Monitoring Alerts
|
||||
- [ ] Emergency access granted
|
||||
- [ ] Access duration extended
|
||||
- [ ] Approved access not used within 30 minutes
|
||||
- [ ] Unusual access patterns detected
|
||||
- [ ] Approval SLA breached
|
||||
- [ ] Revocation failure
|
||||
@@ -0,0 +1,27 @@
|
||||
# Standards and References - Just-In-Time Access Provisioning
|
||||
|
||||
## NIST Standards
|
||||
- **NIST SP 800-207**: Zero Trust Architecture - Section 3 (Logical Components)
|
||||
- **NIST SP 800-53 Rev 5**:
|
||||
- AC-2(2): Automated Temporary and Emergency Account Management
|
||||
- AC-2(3): Disable Accounts
|
||||
- AC-6: Least Privilege
|
||||
- AC-6(5): Privileged Accounts
|
||||
- **NIST SP 1800-35**: Implementing a Zero Trust Architecture
|
||||
|
||||
## Zero Trust Frameworks
|
||||
- **CISA Zero Trust Maturity Model**: Identity pillar - dynamic access provisioning
|
||||
- **DoD Zero Trust Reference Architecture**: JIT/JEA requirements
|
||||
- **Forrester ZTX**: Extended Zero Trust with JIT access
|
||||
|
||||
## Tools and Platforms
|
||||
- **Microsoft Entra PIM**: Privileged Identity Management with JIT elevation
|
||||
- **CyberArk JIT**: Privileged access on-demand
|
||||
- **SailPoint**: Identity governance with access request workflows
|
||||
- **HashiCorp Boundary**: Just-in-time access to infrastructure
|
||||
- **StrongDM**: Dynamic access management
|
||||
|
||||
## Compliance
|
||||
- **SOX**: Least privilege for financial system access
|
||||
- **PCI DSS 4.0**: Requirement 7.2 - Access based on need to know
|
||||
- **HIPAA**: Minimum necessary standard for PHI access
|
||||
@@ -0,0 +1,55 @@
|
||||
# Just-In-Time Access Provisioning Workflows
|
||||
|
||||
## Workflow 1: Standard JIT Access Request
|
||||
|
||||
### Steps:
|
||||
1. User submits access request via self-service portal
|
||||
2. Request includes: target resource, duration, business justification
|
||||
3. System calculates risk score based on resource sensitivity and user context
|
||||
4. Risk-based routing:
|
||||
- Low risk (< 1 hr, non-privileged): Auto-approve
|
||||
- Medium risk: Route to resource owner for approval
|
||||
- High risk (privileged, production): Dual approval required
|
||||
5. Approver notified via email/Slack/Teams
|
||||
6. Approver reviews and approves/denies with comments
|
||||
7. On approval: system provisions access with time-bound constraint
|
||||
8. User notified of access grant with expiration time
|
||||
9. At expiration: system automatically revokes access
|
||||
10. All events logged for audit trail
|
||||
|
||||
## Workflow 2: Emergency JIT Access (Break-Glass)
|
||||
|
||||
### Steps:
|
||||
1. User declares emergency and requests immediate access
|
||||
2. System grants access immediately without pre-approval
|
||||
3. Access limited to shorter maximum duration (e.g., 2 hours)
|
||||
4. Security team notified of emergency access grant
|
||||
5. User must provide justification within 24 hours
|
||||
6. Manager and security team perform post-facto review
|
||||
7. If review finds access unjustified: security incident opened
|
||||
8. All emergency access events flagged in audit reports
|
||||
|
||||
## Workflow 3: Privileged Elevation with PAM Integration
|
||||
|
||||
### Steps:
|
||||
1. User requests privilege elevation through JIT portal
|
||||
2. Approval obtained per risk-based workflow
|
||||
3. JIT system triggers PAM credential checkout
|
||||
4. PSM session initiated with time-bound credential
|
||||
5. User performs privileged operations via isolated session
|
||||
6. Session recorded for audit
|
||||
7. At expiration: session terminated, credential checked in, password rotated
|
||||
8. JIT access record closed
|
||||
|
||||
## Workflow 4: Vendor/Third-Party JIT Access
|
||||
|
||||
### Steps:
|
||||
1. Internal sponsor submits access request on behalf of vendor
|
||||
2. Request includes: vendor identity, scope, duration, project reference
|
||||
3. Dual approval required (sponsor manager + security)
|
||||
4. Temporary account created with MFA enrollment
|
||||
5. Access restricted to specified resources only
|
||||
6. Network access limited to authorized segments
|
||||
7. Session monitoring enabled
|
||||
8. Account deactivated at expiration
|
||||
9. Account deleted after 30-day retention period
|
||||
@@ -0,0 +1,373 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Just-In-Time Access Provisioning Engine
|
||||
|
||||
Manages JIT access requests, approval workflows, time-bound grants,
|
||||
automatic revocation, and audit logging for zero-standing-privilege
|
||||
implementations.
|
||||
"""
|
||||
|
||||
import json
|
||||
import datetime
|
||||
import secrets
|
||||
from typing import Dict, List, Optional
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class RiskLevel(Enum):
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
CRITICAL = "critical"
|
||||
|
||||
|
||||
class RequestStatus(Enum):
|
||||
PENDING = "pending"
|
||||
APPROVED = "approved"
|
||||
DENIED = "denied"
|
||||
ACTIVE = "active"
|
||||
EXPIRED = "expired"
|
||||
REVOKED = "revoked"
|
||||
EMERGENCY = "emergency"
|
||||
|
||||
|
||||
@dataclass
|
||||
class JITAccessRequest:
|
||||
"""A just-in-time access request."""
|
||||
request_id: str
|
||||
requester: str
|
||||
target_resource: str
|
||||
resource_type: str # server, database, application, cloud_role
|
||||
requested_duration_minutes: int
|
||||
justification: str
|
||||
risk_level: RiskLevel = RiskLevel.MEDIUM
|
||||
status: RequestStatus = RequestStatus.PENDING
|
||||
approvers: List[str] = field(default_factory=list)
|
||||
approved_by: List[str] = field(default_factory=list)
|
||||
denied_by: str = ""
|
||||
created_at: str = ""
|
||||
granted_at: str = ""
|
||||
expires_at: str = ""
|
||||
revoked_at: str = ""
|
||||
is_emergency: bool = False
|
||||
ticket_id: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
class ResourcePolicy:
|
||||
"""Policy for a protected resource."""
|
||||
resource_pattern: str
|
||||
resource_type: str
|
||||
max_duration_minutes: int
|
||||
risk_level: RiskLevel
|
||||
auto_approve: bool = False
|
||||
required_approvals: int = 1
|
||||
approver_roles: List[str] = field(default_factory=list)
|
||||
mfa_required: bool = True
|
||||
session_recording: bool = False
|
||||
|
||||
|
||||
class JITAccessEngine:
|
||||
"""Manages the full JIT access lifecycle."""
|
||||
|
||||
def __init__(self):
|
||||
self.requests: Dict[str, JITAccessRequest] = {}
|
||||
self.policies: List[ResourcePolicy] = []
|
||||
self.audit_log: List[Dict] = []
|
||||
|
||||
def add_policy(self, policy: ResourcePolicy):
|
||||
"""Register a resource access policy."""
|
||||
self.policies.append(policy)
|
||||
|
||||
def _get_policy(self, resource: str, resource_type: str) -> Optional[ResourcePolicy]:
|
||||
"""Find matching policy for a resource."""
|
||||
for policy in self.policies:
|
||||
if policy.resource_type == resource_type:
|
||||
if policy.resource_pattern == "*" or policy.resource_pattern in resource:
|
||||
return policy
|
||||
return None
|
||||
|
||||
def _generate_request_id(self) -> str:
|
||||
return f"JIT-{datetime.datetime.now().strftime('%Y%m%d')}-{secrets.token_hex(4).upper()}"
|
||||
|
||||
def _log_event(self, event_type: str, request_id: str, details: Dict):
|
||||
"""Record audit event."""
|
||||
self.audit_log.append({
|
||||
"timestamp": datetime.datetime.now().isoformat(),
|
||||
"event_type": event_type,
|
||||
"request_id": request_id,
|
||||
**details
|
||||
})
|
||||
|
||||
def submit_request(self, requester: str, target_resource: str,
|
||||
resource_type: str, duration_minutes: int,
|
||||
justification: str, is_emergency: bool = False,
|
||||
ticket_id: str = "") -> JITAccessRequest:
|
||||
"""Submit a new JIT access request."""
|
||||
policy = self._get_policy(target_resource, resource_type)
|
||||
if not policy:
|
||||
raise ValueError(f"No policy found for resource type: {resource_type}")
|
||||
|
||||
# Enforce maximum duration
|
||||
actual_duration = min(duration_minutes, policy.max_duration_minutes)
|
||||
if is_emergency:
|
||||
actual_duration = min(actual_duration, 120) # 2-hour max for emergency
|
||||
|
||||
request = JITAccessRequest(
|
||||
request_id=self._generate_request_id(),
|
||||
requester=requester,
|
||||
target_resource=target_resource,
|
||||
resource_type=resource_type,
|
||||
requested_duration_minutes=actual_duration,
|
||||
justification=justification,
|
||||
risk_level=policy.risk_level,
|
||||
created_at=datetime.datetime.now().isoformat(),
|
||||
is_emergency=is_emergency,
|
||||
ticket_id=ticket_id
|
||||
)
|
||||
|
||||
if is_emergency:
|
||||
# Emergency: grant immediately, require post-facto review
|
||||
request.status = RequestStatus.EMERGENCY
|
||||
now = datetime.datetime.now()
|
||||
request.granted_at = now.isoformat()
|
||||
request.expires_at = (now + datetime.timedelta(minutes=actual_duration)).isoformat()
|
||||
self._log_event("EMERGENCY_GRANT", request.request_id, {
|
||||
"requester": requester,
|
||||
"resource": target_resource,
|
||||
"duration_minutes": actual_duration,
|
||||
"justification": justification
|
||||
})
|
||||
elif policy.auto_approve and policy.risk_level == RiskLevel.LOW:
|
||||
# Auto-approve low-risk
|
||||
request.status = RequestStatus.APPROVED
|
||||
request.approved_by = ["AUTO"]
|
||||
self._log_event("AUTO_APPROVED", request.request_id, {
|
||||
"requester": requester,
|
||||
"resource": target_resource,
|
||||
"reason": "Low-risk auto-approve policy"
|
||||
})
|
||||
self._activate_access(request)
|
||||
else:
|
||||
# Route for approval
|
||||
request.approvers = policy.approver_roles
|
||||
request.status = RequestStatus.PENDING
|
||||
self._log_event("REQUEST_SUBMITTED", request.request_id, {
|
||||
"requester": requester,
|
||||
"resource": target_resource,
|
||||
"required_approvals": policy.required_approvals,
|
||||
"approvers": policy.approver_roles
|
||||
})
|
||||
|
||||
self.requests[request.request_id] = request
|
||||
return request
|
||||
|
||||
def approve_request(self, request_id: str, approver: str) -> JITAccessRequest:
|
||||
"""Approve a JIT access request."""
|
||||
request = self.requests.get(request_id)
|
||||
if not request:
|
||||
raise ValueError(f"Request not found: {request_id}")
|
||||
if request.status not in (RequestStatus.PENDING,):
|
||||
raise ValueError(f"Request {request_id} is not pending approval")
|
||||
|
||||
request.approved_by.append(approver)
|
||||
policy = self._get_policy(request.target_resource, request.resource_type)
|
||||
required = policy.required_approvals if policy else 1
|
||||
|
||||
self._log_event("APPROVAL_RECORDED", request_id, {
|
||||
"approver": approver,
|
||||
"approvals_count": len(request.approved_by),
|
||||
"required": required
|
||||
})
|
||||
|
||||
if len(request.approved_by) >= required:
|
||||
request.status = RequestStatus.APPROVED
|
||||
self._activate_access(request)
|
||||
|
||||
return request
|
||||
|
||||
def deny_request(self, request_id: str, denier: str, reason: str = "") -> JITAccessRequest:
|
||||
"""Deny a JIT access request."""
|
||||
request = self.requests.get(request_id)
|
||||
if not request:
|
||||
raise ValueError(f"Request not found: {request_id}")
|
||||
|
||||
request.status = RequestStatus.DENIED
|
||||
request.denied_by = denier
|
||||
self._log_event("REQUEST_DENIED", request_id, {
|
||||
"denied_by": denier,
|
||||
"reason": reason
|
||||
})
|
||||
return request
|
||||
|
||||
def _activate_access(self, request: JITAccessRequest):
|
||||
"""Activate the approved access grant."""
|
||||
now = datetime.datetime.now()
|
||||
request.status = RequestStatus.ACTIVE
|
||||
request.granted_at = now.isoformat()
|
||||
request.expires_at = (now + datetime.timedelta(
|
||||
minutes=request.requested_duration_minutes
|
||||
)).isoformat()
|
||||
|
||||
self._log_event("ACCESS_ACTIVATED", request.request_id, {
|
||||
"requester": request.requester,
|
||||
"resource": request.target_resource,
|
||||
"granted_at": request.granted_at,
|
||||
"expires_at": request.expires_at
|
||||
})
|
||||
|
||||
def check_expirations(self) -> List[JITAccessRequest]:
|
||||
"""Check and revoke expired access grants."""
|
||||
now = datetime.datetime.now()
|
||||
expired = []
|
||||
|
||||
for request in self.requests.values():
|
||||
if request.status in (RequestStatus.ACTIVE, RequestStatus.EMERGENCY):
|
||||
if request.expires_at:
|
||||
expiry = datetime.datetime.fromisoformat(request.expires_at)
|
||||
if now >= expiry:
|
||||
request.status = RequestStatus.EXPIRED
|
||||
request.revoked_at = now.isoformat()
|
||||
expired.append(request)
|
||||
self._log_event("ACCESS_EXPIRED", request.request_id, {
|
||||
"requester": request.requester,
|
||||
"resource": request.target_resource,
|
||||
"expired_at": request.revoked_at
|
||||
})
|
||||
|
||||
return expired
|
||||
|
||||
def revoke_access(self, request_id: str, reason: str = "") -> JITAccessRequest:
|
||||
"""Manually revoke an active access grant."""
|
||||
request = self.requests.get(request_id)
|
||||
if not request:
|
||||
raise ValueError(f"Request not found: {request_id}")
|
||||
|
||||
request.status = RequestStatus.REVOKED
|
||||
request.revoked_at = datetime.datetime.now().isoformat()
|
||||
self._log_event("ACCESS_REVOKED", request_id, {
|
||||
"requester": request.requester,
|
||||
"resource": request.target_resource,
|
||||
"reason": reason
|
||||
})
|
||||
return request
|
||||
|
||||
def get_active_grants(self) -> List[JITAccessRequest]:
|
||||
"""List all currently active access grants."""
|
||||
return [r for r in self.requests.values()
|
||||
if r.status in (RequestStatus.ACTIVE, RequestStatus.EMERGENCY)]
|
||||
|
||||
def get_metrics(self) -> Dict:
|
||||
"""Calculate JIT access metrics."""
|
||||
all_requests = list(self.requests.values())
|
||||
total = len(all_requests)
|
||||
if total == 0:
|
||||
return {"total": 0}
|
||||
|
||||
by_status = {}
|
||||
for r in all_requests:
|
||||
by_status[r.status.value] = by_status.get(r.status.value, 0) + 1
|
||||
|
||||
emergency_count = sum(1 for r in all_requests if r.is_emergency)
|
||||
|
||||
# Calculate mean time to access
|
||||
approved = [r for r in all_requests if r.granted_at and r.created_at]
|
||||
if approved:
|
||||
total_wait = sum(
|
||||
(datetime.datetime.fromisoformat(r.granted_at) -
|
||||
datetime.datetime.fromisoformat(r.created_at)).total_seconds()
|
||||
for r in approved
|
||||
)
|
||||
mean_tta = total_wait / len(approved) / 60 # minutes
|
||||
else:
|
||||
mean_tta = 0
|
||||
|
||||
return {
|
||||
"total_requests": total,
|
||||
"by_status": by_status,
|
||||
"emergency_grants": emergency_count,
|
||||
"active_grants": len(self.get_active_grants()),
|
||||
"mean_time_to_access_minutes": round(mean_tta, 1),
|
||||
"audit_events": len(self.audit_log)
|
||||
}
|
||||
|
||||
def generate_report(self) -> str:
|
||||
"""Generate JIT access report."""
|
||||
metrics = self.get_metrics()
|
||||
active = self.get_active_grants()
|
||||
|
||||
lines = [
|
||||
"=" * 70,
|
||||
"JUST-IN-TIME ACCESS PROVISIONING REPORT",
|
||||
"=" * 70,
|
||||
f"Report Date: {datetime.datetime.now().isoformat()}",
|
||||
f"Total Requests: {metrics['total_requests']}",
|
||||
f"Active Grants: {metrics['active_grants']}",
|
||||
f"Emergency Grants: {metrics['emergency_grants']}",
|
||||
f"Mean Time to Access: {metrics['mean_time_to_access_minutes']} minutes",
|
||||
f"Audit Events: {metrics['audit_events']}",
|
||||
"-" * 70,
|
||||
"",
|
||||
"STATUS BREAKDOWN:",
|
||||
]
|
||||
for status, count in metrics.get("by_status", {}).items():
|
||||
lines.append(f" {status}: {count}")
|
||||
lines.append("")
|
||||
|
||||
if active:
|
||||
lines.append("ACTIVE GRANTS:")
|
||||
lines.append("-" * 40)
|
||||
for r in active:
|
||||
flag = " [EMERGENCY]" if r.is_emergency else ""
|
||||
lines.append(f" {r.request_id}: {r.requester} -> {r.target_resource}{flag}")
|
||||
lines.append(f" Expires: {r.expires_at}")
|
||||
lines.append(f" Justification: {r.justification}")
|
||||
lines.append("")
|
||||
|
||||
lines.append("=" * 70)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main():
|
||||
"""Demo JIT access engine."""
|
||||
engine = JITAccessEngine()
|
||||
|
||||
# Define resource policies
|
||||
engine.add_policy(ResourcePolicy(
|
||||
resource_pattern="*", resource_type="read_only",
|
||||
max_duration_minutes=60, risk_level=RiskLevel.LOW,
|
||||
auto_approve=True, required_approvals=0
|
||||
))
|
||||
engine.add_policy(ResourcePolicy(
|
||||
resource_pattern="*", resource_type="production_server",
|
||||
max_duration_minutes=240, risk_level=RiskLevel.HIGH,
|
||||
auto_approve=False, required_approvals=2,
|
||||
approver_roles=["manager", "security_team"],
|
||||
session_recording=True
|
||||
))
|
||||
engine.add_policy(ResourcePolicy(
|
||||
resource_pattern="*", resource_type="database_admin",
|
||||
max_duration_minutes=120, risk_level=RiskLevel.CRITICAL,
|
||||
auto_approve=False, required_approvals=2,
|
||||
approver_roles=["dba_lead", "security_team"],
|
||||
mfa_required=True, session_recording=True
|
||||
))
|
||||
|
||||
# Submit requests
|
||||
r1 = engine.submit_request("alice", "docs-server", "read_only", 30,
|
||||
"Need to check documentation")
|
||||
r2 = engine.submit_request("bob", "prod-web-01", "production_server", 120,
|
||||
"Deploy hotfix for CVE-2026-1234", ticket_id="INC-5678")
|
||||
r3 = engine.submit_request("charlie", "prod-db-01", "database_admin", 60,
|
||||
"Critical production outage", is_emergency=True)
|
||||
|
||||
# Approve prod server access
|
||||
engine.approve_request(r2.request_id, "manager_dave")
|
||||
engine.approve_request(r2.request_id, "security_eve")
|
||||
|
||||
print(engine.generate_report())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user