CloudWorkstation Secure Invitation Architecture¶
This document outlines the architecture for the enhanced secure invitation system in CloudWorkstation v0.4.3. The system provides a multi-level permissions model with device binding capabilities, similar to modern passkey systems.
Goals¶
- Prevent Casual Sharing: Block unauthorized redistribution of invitation profiles
- Support Multi-Device: Allow legitimate users to use profiles on their multiple devices
- Hierarchical Permissions: Enable delegation of invitation authority with constraints
- Low Friction: Maintain excellent user experience for legitimate users
- Administrator Visibility: Provide tools to track and manage invitation usage
Security Model¶
Enhanced Permission System¶
CloudWorkstation implements a hierarchical permission model for invitation-based profiles:
| Permission | Description |
|---|---|
can_invite | Whether this profile can create sub-invitations |
transferable | Whether this profile can be exported/shared |
device_bound | Whether the profile is restricted to specific devices |
max_devices | Maximum number of devices allowed per user (1-5) |
These permissions follow a hierarchical model: - A user cannot grant permissions they don't have - Sub-invitations inherit restrictions from their parent - Administrators can see the full invitation chain
Keychain-Based Security¶
For device binding, CloudWorkstation uses the system's native secure storage:
- macOS: Apple Keychain
- Windows: Windows Credential Manager
- Linux: Secret Service API (GNOME Keyring/KWallet)
This approach provides: 1. Secure storage of binding material 2. Native multi-device sync (on platforms that support it) 3. Protection against casual profile sharing
S3-Based Registry¶
A lightweight registry in S3 tracks invitation usage:
s3://cloudworkstation-invitations/
├── registry/
│ └── registry.json # Master registry of all invitations
├── invitations/
│ ├── inv-abc123/
│ │ ├── metadata.json # Invitation details
│ │ └── devices.json # Authorized devices
│ └── inv-def456/
│ ├── metadata.json
│ └── devices.json
└── audit/
└── access-log.ndjson # Activity logs
The registry enables: - Validation of authorized devices - Usage tracking for administrators - Revocation of compromised invitations - Audit logging of invitation activities
User Flows¶
Creating Invitations with Security Settings¶
# Professor creates TA invitation with invitation abilities
cws profiles invitations create ta-access --type admin \
--can-invite=true --transferable=false --device-bound=true --max-devices=3
# TA creates student invitation with restricted permissions
cws profiles invitations create student-access --type read_only \
--can-invite=false --transferable=false --device-bound=true --max-devices=2
Accepting an Invitation¶
When a user accepts an invitation, the system:
- Validates the invitation token
- Creates a device binding in the system keychain
- Registers the device in the S3 registry
- Creates a profile with a reference to the keychain item
For seamless multi-device use: - On Apple platforms, iCloud Keychain can automatically sync the binding - On other platforms, an enrollment code is generated for additional devices
Using Multiple Devices¶
The system supports multiple approaches for multi-device usage:
- Native Keychain Sync: For platforms with built-in keychain sync (Apple)
- Enrollment Flow: For other platforms
- Device Management:
Technical Implementation¶
Enhanced Data Models¶
// Enhanced InvitationToken
type InvitationToken struct {
// Basic invitation data
Token string `json:"token"`
OwnerProfile string `json:"owner_profile"`
Name string `json:"name"`
Type InvitationType `json:"type"`
Created time.Time `json:"created"`
Expires time.Time `json:"expires"`
// Security attributes
CanInvite bool `json:"can_invite"`
Transferable bool `json:"transferable"`
DeviceBound bool `json:"device_bound"`
MaxDevices int `json:"max_devices"`
// Parentage tracking
ParentToken string `json:"parent_token,omitempty"`
}
// Enhanced Profile
type Profile struct {
// Basic profile data
Type string `json:"type"`
Name string `json:"name"`
AWSProfile string `json:"aws_profile"`
// Security attributes
CanInvite bool `json:"can_invite"`
Transferable bool `json:"transferable"`
DeviceBound bool `json:"device_bound"`
BindingRef string `json:"binding_ref,omitempty"`
}
Keychain Integration¶
CloudWorkstation uses a cross-platform abstraction for secure storage:
// Cross-platform keychain interface
type KeychainProvider interface {
Store(key string, data []byte) error
Retrieve(key string) ([]byte, error)
Exists(key string) bool
Delete(key string) error
}
// Platform implementations
func NewKeychainProvider() KeychainProvider {
switch runtime.GOOS {
case "darwin":
return &MacOSKeychain{}
case "windows":
return &WindowsCredentialManager{}
default:
return &LinuxSecretService{}
}
}
Device Binding Process¶
-
Create Binding: When accepting an invitation
func createDeviceBinding(profile *Profile, invitation *InvitationToken) error { // Generate device identifier deviceID := generateDeviceID() // Create binding material binding := BindingMaterial{ DeviceID: deviceID, ProfileID: profile.AWSProfile, InvitationToken: invitation.Token, Created: time.Now(), } // Store in keychain bindingData, _ := json.Marshal(binding) bindingRef := fmt.Sprintf("com.cloudworkstation.profile.%s", profile.AWSProfile) keychain := NewKeychainProvider() if err := keychain.Store(bindingRef, bindingData); err != nil { return fmt.Errorf("failed to create binding: %w", err) } // Save reference in profile profile.BindingRef = bindingRef // Register with S3 registry (background) go registerWithS3Registry(invitation.Token, deviceID) return nil } -
Validate Binding: When using a profile
func validateBinding(profile *Profile) error { if !profile.DeviceBound { return nil // No validation needed } keychain := NewKeychainProvider() bindingData, err := keychain.Retrieve(profile.BindingRef) if err != nil || bindingData == nil { return errors.New("profile not authorized for this device") } // Binding exists, allow usage return nil }
Administrator Tools¶
Administrators can monitor and manage invitation usage:
# View usage statistics
cws profiles invitations usage INVITATION_TOKEN
# Revoke specific device
cws profiles invitations revoke-device INVITATION_TOKEN DEVICE_ID
# Revoke entire invitation
cws profiles invitations revoke INVITATION_TOKEN
The GUI will provide visual dashboards showing: - Active invitations and their status - User and device counts - Usage patterns and anomalies
Security Considerations¶
Security Strengths¶
- Keychain Protection: Leverages OS security for credential protection
- Multi-Factor by Design: Requires both profile config and keychain binding
- Hierarchical Control: Administrators maintain control over delegation chain
- Visibility: All invitation usage is trackable
Security Limitations¶
- Client-Side Security: Can't fully protect against determined local attackers
- Platform Variations: Different security levels across operating systems
- Recovery Complexity: Recovery procedures add complexity
Mitigations¶
- Background Validation: Periodic checks against S3 registry
- Usage Analytics: Detecting unusual patterns
- Revocation Capability: Quick revocation of compromised invitations
- Audit Logging: All security events are logged
Implementation Timeline¶
The secure invitation system will be implemented in phases:
- Phase 1 (v0.4.3): Enhanced data models and keychain integration
- Phase 2 (v0.4.4): S3 registry and basic validation
- Phase 3 (v0.4.5): Administrator tools and advanced monitoring
- Phase 4 (v0.5.0): GUI integration and analytics dashboard
Integration with Existing Features¶
This feature enhances and integrates with:
- Profile Management: Adds security attributes to profiles
- Invitation System: Extends the invitation model with security constraints
- Export/Import: Enforces transferability restrictions
- CLI/GUI: Adds security-related commands and interfaces
Conclusion¶
The secure invitation architecture provides a robust solution for controlling profile sharing while maintaining an excellent user experience. By leveraging OS-native security features and a lightweight server component, it achieves the security goals without adding significant friction for legitimate users.
This approach is particularly well-suited for educational and research environments where preventing casual sharing is important, but extremely high security against sophisticated attacks is not required.