Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ LOG_LEVEL=debug make run
- **Heimdall Integration**: All messages validated against JWT service
- **Multiple Audiences**: Configurable audience validation
- **Principal Parsing**: Authorization header and X-On-Behalf-Of delegation support
- **Machine User Detection**: `clients@` prefix identification
- **Machine User Detection**: `@clients` suffix identification

**Input Validation:**

Expand Down
12 changes: 8 additions & 4 deletions internal/infrastructure/auth/auth_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,12 @@ func (r *AuthRepository) ParsePrincipals(ctx context.Context, headers map[string
}
authorizedPrincipals = append(authorizedPrincipals, principalEntity)

if strings.HasPrefix(principal, constants.MachineUserPrefix) {
if strings.HasSuffix(principal, constants.MachineUserSuffix) {
isMachineUser = true
r.logger.Info("Machine user detected in authorization header",
"auth_id", authID,
"principal", r.safePrincipalLog(principal),
"machine_user_prefix", constants.MachineUserPrefix)
"machine_user_suffix", constants.MachineUserSuffix)
Comment thread
emsearcy marked this conversation as resolved.
}

r.logger.Debug("Authorization principal parsed successfully",
Expand Down Expand Up @@ -486,7 +486,11 @@ func (r *AuthRepository) safePrincipalLog(principal string) string {
if principal == "" {
return "<empty>"
}
// Don't log full email addresses for privacy
// Machine users are not personal information and should be logged in full for debugging.
if r.isMachineUser(principal) {
return principal
}
// Don't log full email addresses for privacy.
if strings.Contains(principal, "@") {
parts := strings.Split(principal, "@")
if len(parts) == 2 {
Expand All @@ -498,5 +502,5 @@ func (r *AuthRepository) safePrincipalLog(principal string) string {

// isMachineUser checks if a principal is a machine user
func (r *AuthRepository) isMachineUser(principal string) bool {
return strings.HasPrefix(principal, constants.MachineUserPrefix)
return strings.HasSuffix(principal, constants.MachineUserSuffix)
}
7 changes: 6 additions & 1 deletion internal/infrastructure/auth/auth_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -452,14 +452,19 @@ func TestAuthRepository_HelperMethods(t *testing.T) {
result = repo.safePrincipalLog("user@example.com")
assert.Equal(t, "user@***", result)

// Test machine user principal (should be logged in full)
machineUserPrincipal := "test-machine" + constants.MachineUserSuffix
result = repo.safePrincipalLog(machineUserPrincipal)
assert.Equal(t, machineUserPrincipal, result)

// Test non-email principal
result = repo.safePrincipalLog("machine-user-123")
assert.Equal(t, "machine-user-123", result)
})

t.Run("isMachineUser", func(t *testing.T) {
// Test machine user
result := repo.isMachineUser(constants.MachineUserPrefix + "test-machine")
result := repo.isMachineUser("test-machine" + constants.MachineUserSuffix)
Comment thread
emsearcy marked this conversation as resolved.
assert.True(t, result)

// Test regular user
Expand Down
2 changes: 1 addition & 1 deletion pkg/constants/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const (
BearerPrefix = "bearer "

// Machine user identifier
MachineUserPrefix = "clients@"
MachineUserSuffix = "@clients"

// Error messages for authentication
ErrInvalidToken = "invalid token"
Expand Down
Loading