@startuml
' Identity Management and Authentication architecture for Torproject
database "LDAP" {
  map "torPerson" as torPerson {
    uuid => number
    uid => username
    uidNumber => number
    gidNumber => number
    gecos => string
    loginShell => enum[bash,zsh,...]
    keyFingerPrint => string
    cn => string
    sn => string
    displayName => string
    userPassword => hash
    mail => e-mail address
    emailForward => e-mail address
    sshRSAAuthKey => string
    memberOf => torGroup
  }
  map "torGroup" as torGroup {
    gid => groupname
    description => string
    manager => torPerson
    member => torPerson
  }
}
database "mailUsers" {
  map "accessTokens" as mailToken {
    uuid => number
    mail => e-mail address
    description => string
    token => string
  }
}
component "Submission" {
}
component "HR" {
  map "employee" as employee {
    uuid => number
    cn => string
    sn => string
    ... => ?
  }
}
component "IdM" {
}
component "CC membership repo" as CCrepo {
  map "core contributor" as CC {
    uuid => number
    displayName => string
    mail => e-mail address
    membership => boolean
    TPI => boolean
  }
}
component "TPA special users repo" as TPArepo {
  map "TPA special user" as tpaUser {
    uuid => number
    uid => name
    displayName => string
    ... => ??
  }
}
component "SSO" {
}
component "Puppet" {
  map "rbac::users" as puppetUser {
    uuid => number
    id => username
    uid => uidNumber
    shell => loginShell
    sshkey => sshRSAAuthKey
    mail => mail
    pgpkey => keyFingerPrint
  }
  map "rbac::roles" as puppetRole {
    id => gid
    member => member
  }
}
component "Selfservice Portal" as SS {
}
component "Nextcloud" {
}
component "Mailman" {
}
component "Forum" {
}
component "Gitlab" {
}
component "CiviCRM" {
}
component "BTCPayServer" {
}
component "Metrics" {
}
component "RT" {
}
component "Remote.com" as Remote {
}
component "Static mirror" as Mirror {
}
component "Limesurvey" as Limesurvey {
}
component "Chat" as Chat {
' getting decent access control on our weird amalgamation of IRC and matrix is going
' to be tricky, so let's defer until it's clear what the future of chat will be,
' because if we go for something like rocketchat, we can simply hook it to SSO and
' call it a day
}
component "SVN" as SVN {
' SVN is similar to chat in that it's not trivial to implement better access control
' and the service is deprecated anyway, so fixing this is out of scope.
}
component "Debian archive" as Deb {
' i'm not sure how authentication is implemented here or what is should look like,
' but i guess we want it puppet-based?
}
node "Server" {
  component "PAM" {
  }
  map "posixUser" as posixUser {
    uid => username
    shell => loginShell
    ... => ...
  }
}
Submission -[#red]> mailToken
' we don't want people storing their LDAP password, so we'll use a separate database
' with access tokens for authentication to the submission server
SS -- mailToken
' users should be able to manage their e-mail access tokens in the selfservice portal
Metrics-[#red]> SSO
Nextcloud -[#red]> SSO
RT -[#red]> SSO
Limesurvey -[#red]> SSO
Remote -[#red]> SSO
Nextcloud -r--> LDAP
' can we configure nextcloud to lookup users in LDAP but authenticate to SAML?
' that way we could use JIT provisioning and for deprovisioning use
' https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_auth_ldap_cleanup.html
Mailman -[#red]> SSO
IdM .. Mailman
' IdM scripts can check if employees and core contributors are subscribed to the
' internal and employees lists and if there are list members who shouldn't be there
' and report anomalies to the list owners
Forum -[#red]> SSO
' forum will keep its own user/password database next to the option for SSO login.
' provisioning happens JIT at SSO login, deprovisioning is probably not needed
Gitlab -[#red]> SSO
CiviCRM -[#red]> SSO
' we can use auth_mellon to replace the current basic auth and configure drupal to
' use SAML, this will make the double-login-thing seamless for end users
CiviCRM -> LDAP
' for provisioning and deprovisioning of users, we can use
' https://www.drupal.org/docs/contributed-modules/ldap-integration/import-users-from-ldap
SS -[#red]> SSO
' if we opt for lemonldap-ng, selfservice is part of the SSO, else the authentication
' might get a bit more complicated
BTCPayServer -> IdM
' BTCPayServer doesn't seem to have any SSO options, so we'll have to have some IdM
' script call its API to do user provisioning
IdM -l.. torPerson::uuid
' IdM scripts match everyone in the identity sources with an LDAP entry and vice versa
' if anything is out of sync, a Gitlab issue will be created so TPA can fix it
IdM -l.. torGroup
' IdM scripts check that certain groups in LDAP (e.g., employees) match the corresponding
' identity source and vice versa. Perhaps more group data can be pulled from HR that
' should also stay in sync. Any anomalies will be reported in a Gitlab issue.
IdM ..> Gitlab
' IdM scripts report to gitlab
PAM -[#red]> torPerson::userPassword
' configure PAM to use LDAP (at least for sudo), but do *not* configure nss to use LDAP
posixUser -> Puppet
' provisioning and deprovisioning of users happens through puppet-rbac
Mirror -> Puppet
' access to the static mirrors is controlled by puppet-rbac
puppetUser -> torPerson
puppetRole -> torGroup
' puppet reads user and role/group data from LDAP
SS -l-- torPerson::userPassword
SS -l-- torPerson::emailForward
SS -l-- torPerson::displayName
SS -l-- torPerson::cn
SS -l-- torPerson::sn
SS -l-- torPerson::loginShell
' users can manage their own password, mailforward, name, shell, etc. through the
' selfservice portal
SS -l-- torPerson::sshRSAAuthKey
' a risk assessment is required to determine if the selfservice portal is secure enough
' to grant access to ssh key management
SS -l-- torPerson::keyFingerPrint
' a risk assessment is required to determine if the selfservice portal is secure enough
' to grant access to pgp key management
Deb -> Puppet
' the debian archive should provision users and add their PGP from puppet
torGroup::member -- torPerson::memberOf
' refint should be configured to keep groups' member and users' memberOf attributes
' in sync
IdM --> CCrepo
' IdM scripts should pull data from the core contributor membership list
IdM --> HR
' IdM scripts should pull data from HR (let's hope they get a decent API)
IdM --> TPArepo
' IdM scripts should pull data from TPA special users repo (for weird edge cases)
SSO --> LDAP
' SSO uses LDAP for password authentication and does MFA internally
SSO -[#red]> torPerson::userPassword
legend left
{{
  scale 0.75

  card Legend {
    together {
      (a) -[#red]-> (b)  : Authenticates to
    }
    together  {
      (c) -[#black]-> (d) : Gets user data from
    }
    together  {
      (e) -[#black]- (f) : Synchronises with
    }
    together  {
      (g) .. (h) : Verifies integrity
    }
    together  {
      (i) ..> (j) : Reports to
    }
}}
end legend
@enduml
