Token based solutions

Diana Gudu, Marcus Hardt, Gabriel Zachmann

Sep 2023

Federated Identities 101

Why would anyone use federated identities?

  • As a user
    • Single Sign-On (SSO)
    • No additional service credentials
    • => Increase in security
    • Less prior registration
      • => Increase in convenience
    • Act as a member of a community (VO)
      • => Increase in Usability
  • As a service
    • Offload identity management to home organisation
    • Offload authorisation management to federation (VOs)
      • => Reduced cost
      • => Improved user data quality
    • Increased security
    • Potential of cooperation across services

Use Cases

Use Case: API Access

  • Why would you want to do it?
    • Web apps: Web frontend + REST access to backend
    • Cloud services:
      • Create Openstack VM from commandline
      • Access storage
      • Github
  • Protect your REST API with OIDC: => flaat
  • Access a REST API with OIDC: => oidc-agent + curl

Use Case: Grid

  • X.509 => Tokens
  • All use cases from grid should work with tokens:
  • Service migration -> Service developers => flaat
  • How does the user get tokens => oidc-agent
  • But: can we just replace X.509 certificates with tokens?
    • Tokens cannot be revoked
    • Tokens (should) live much shorter
    • Long-running jobs need fresh tokens
      • => Look at mytoken

Use Case: Shell Access

  • I started my Openstack VM, now what?
    • I need to access remote services (e.g. using tokens) => access tokens
    • I need an access token throughout the lifetime of the VM => mytoken, maybe vault
  • Similar for HPC
    • I need to ssh into my HPC-cluster / VM => ssh-oidc/motley-cue

Fun with OIDC

Getting access tokens

https://github.com/indigo-dc/oidc-agent
























  • Problem 1: OIDC is not designed to give access tokens to users
  • Problem 2: Access tokens expire rather soon (actually this is a good thing!)
  • Solution: oidc-agent (think “ssh-agent”)
  • Tool for OIDC access tokens on the commandline
    • WLCG, Unicore, FedCloud, ARC-CE, Japan HPC, Fenix, … (we lost track, …)
    • Obtain refresh token
      • Run an OIDC web flow
      • Crypt it
      • Store it
      • Load to RAM when needed (also crypted when in RAM)
  • Key Features
    • Packaged for Major Systems [Debian, Ubuntu, Fedora, Centos, Suse, MacOS, Windows]
    • X-Session integration
    • Graphical Query
    • mytoken integration
# Example:
# Step 1: Obtain a refresh token from your issuer:
    oidc-gen --pub --issuer https://aai.egi.eu/auth/realms/egi --scope "max" test
        <follow the flow in your browser ...>

# Step 2: Get access tokens:
    oidc-token test

# Step 3: Take a look at the token, and the userinfo endpoint:
for T in $(oidc-token test| tr '.' '\n' ); do
    echo $T | base64 -di 2>/dev/null | jq --indent 4 2>/dev/null
done
# Step 3: Or just do it in python
    pip install flaat                  
    flaat-userinfo `oidc-token test`

                                          Result




















# Information stored inside the access token:
{   "body": {
        "auth_time": 1664276918,
        "authenticating_authority": "https://idp.scc.kit.edu/idp/shibboleth",
        "azp": "oidc-agent",
        "exp": 1679063615,
        "iat": 1679060015,
        "iss": "https://aai.egi.eu/auth/realms/egi",
        "jti": "8fbd6ec9-f6cc-431a-93dd-fd11aee7efbd",
        "scope": "openid eduperson_unique_id offline_access eduperson_scoped_affiliation eduperson_entitlement profile email",
        "session_state": "18489eb8-6715-4a3a-a56c-42121be20b84",
        "sid": "18489eb8-6715-4a3a-a56c-42121be20b84",
        "sub": "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu",
        "typ": "Bearer"
    }, "header": {
        "alg": "RS256",
        "kid": "PUYOirA3Y-d_dGpdj4iJDHw4zHa8IY-bhZdaEj0rjbU",
        "typ": "JWT"
    }, "signature": "TK9z3BMnSslde5pobCk4lSfxOEKMCz17xAFPw0WuSYbAWXM93fbN8yF0aAAM9pK4xm0A_t_JulKjgSZ-nU_ototXoQRhkLZIV59Y5ErFXdeR6SPETSEVVJL7NdON9mdycM0siaQKsl0MYhqVyblCRlsBQkjejyZKzgW1opamGQKaYq_uoG8I4BJsbAJ5rvjNuTMtVTzFjpCXQSVeJNkthSz_C1gNZDHAnWAeGP5cW4PvzIbEqCe-cTKWOfd9u9Y-StSunF-jpr8y0I5_7eQxvOFPC6Vf5lNnPFFxlY25qB10XrTZmFiL-W8qpjaQH-NUFo4cprpHYKsxbBk1aIjw_w",
    "verification": {
        "algorithm": "RS256"
} }
# Information retrieved from userinfo endpoint: {
    "eduperson_assurance": [
        "https://refeds.org/assurance/ATP/ePA-1d",
        "https://refeds.org/assurance/ATP/ePA-1m",
        "https://refeds.org/assurance/IAP/low",
        "https://refeds.org/assurance/profile/cappuccino",
        "https://refeds.org/assurance/IAP/local-enterprise",
        "https://refeds.org/assurance/IAP/medium",
        "https://refeds.org/assurance/ID/unique",
        "https://refeds.org/assurance/ID/eppn-unique-no-reassign",
        "https://aai.egi.eu/LoA#Substantial"
    ], "eduperson_entitlement": [
        "urn:mace:egi.eu:group:covid19.eosc-synergy.eu:admins:role=owner#aai.egi.eu",
        "urn:mace:egi.eu:group:eosc-synergy.eu:role=member#aai.egi.eu",
        [...]
        "urn:mace:egi.eu:group:umsa.cerit-sc.cz:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:umsa.cerit-sc.cz:admins:role=owner#aai.egi.eu"
    ], "eduperson_scoped_affiliation": [
        "employee@kit.edu",
        "member@kit.edu"
    ], "eduperson_unique_id": [ "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu" ],
    "email": "hardt@kit.edu",
    "email_verified": true,
    "family_name": "Hardt",
    "given_name": "Marcus",
    "iss": "https://aai.egi.eu/auth/realms/egi",
    "name": "Marcus Hardt",
    "preferred_username": "mhardt",
    "sub": "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu",
    "voperson_verified_email": [ "hardt@kit.edu" ]
}

More fun

flaat

https://flaat.readthedocs.io

  • Authorisation for REST APIs
  • Flexible python framework
    • Supports flask, AIO, FastAPI














# Example Code (skipping boilerplate)
@routes.get("/authorized_vo")
@flaat.requires(
    get_vo_requirement(
        [
            "urn:geant:h-df.de:group:m-team:feudal-developers",
            "urn:geant:h-df.de:group:MyExampleColab#unity.helmholtz.de",
        ],
        "eduperson_entitlement", match=1,
    )
)
async def authorized_vo(request):
    return web.Response(text="This worked: user has the required entitlement")
# Example call and response
$ http http://localhost:8080/authorized_vo  "Authorization: Bearer `oidc-token login`"
HTTP/1.1 200 OK
Content-Length: 46
Content-Type: text/plain; charset=utf-8
Date: Fri, 17 Mar 2023 13:54:51 GMT
Server: Python/3.11 aiohttp/3.8.3

This worked: user has the required entitlement

What else?

mytoken [1/2]

https://mytoken.data.kit.edu

  • What if you have a long-running job
    • … that also spends some time in a queue
  • mytoken (think “myProxy” done right)
  • Solves this!
  • mytoken-server:
    • gets the refresh token (typical web-flow)
    • encrypts + stores refresh token with mytoken
    • returns the mytoken-token to user
  • user (client):
    • use the mytoken with mytoken-server to get access token

mytoken [2/2]

  • Why is it better than sending refresh-tokens with the job?
  • Features to carefully balance security requirements with use case:
  • Capabilities
    • WHAT can the mytoken do (get ATs, create new MTs, history, introspection, settings, …)
  • Restrictions
    • LIMITATIONS on the token are based on
      • time, IP address space, geolocation, number of usages, scopes, audiences
  • More info: https://mytoken-docs.data.kit.edu
  • Example: https://mytoken.data.kit.edu
  • Using mytoken client from the cmdline
$ mytoken AT --MT $MYTOKEN
eyJ[............]

Combining these solutions….

…for SSH with federated identities

SSH

Kind of holy grail, because:

  • Use federated identity
    • SSH-Server has no direct relation with Organisation where user comes from
  • To log into a Unix account
    • How to find the correct unix account?
  • Authorised by
    • Virtual Organisation membership (entitlement)
    • Assurance
    • Individual user (sub + iss)
  • How to revoke access?
    • User gone
    • Security incident

Approaches

flaat + pam-module

  • PAM Module pam-ssh-oidc developed by PSNC (in Pracelab.PL)
  • pam-ssh-oidc enables two things:
    1. Prompt for “Access Token”
    2. Put access-token into ssh password field
  • pam-module uses flaat for authorisation
  • Prerequisite: the remote user has to exist








# Example
$ oidc-token google # or mytoken AT --MT $MYTOKEN
$ ssh testme@ssh-oidc-demo.data.kit.edu

(testme@ssh-oidc-demo.data.kit.edu) Access Token:
(testme@ssh-oidc-demo.data.kit.edu) Password: 
(testme@ssh-oidc-demo.data.kit.edu) Access Token:

testme@ssh-oidc-demo:~$

flaat + pam-module + motley_cue

https://motley-cue.readthedocs.io

  • motley-cue: Server-side daemon developed in HIFIS (Germany)
  • motley-cue fixes 4 things:
    1. Dynamically provision a user (plugin-based, optional)
      • Pooled-account, “Friendly” username, External username lookup
      • Authorisation based on
        • entitlement (i.e. VO)
        • assurance
        • sub@iss (user whitelist)
    2. If access token is longer than 1kb
      • motley_cue creates a one-time-password (OTP)
    3. Obtain the username from server for you
    4. Admin interface for security incidents
      • suspend / resume user
    • But opens a REST interface on the server





# Example
mccli ssh ssh-oidc-demo.data.kit.edu --oidc google

testme@ssh-oidc-demo:~$

SSH notes

NEW: oinit + motley-cue

  • Make use of ssh-certificates
  • Concept borrows from kerberos’s “kinit
  • New tool: oinit:
    • Use oidc-agent to authenticate to an ssh-online-ca
    • Get ssh certificate (valid for a few hours)
    • Provision user dynamically (if required)
    • Adjust configuration of ~/.ssh/config to work well
  • From there on
    • Use native ssh like ever before:
    • Passwordless (unless a 2nd factor is in the way)
    • Enable advanced usage: git, rsync, …

More SSH Approaches

  • Multiple different approaches exist
  • Smart Shell
    • AWI, SURF
  • SSH Certificates
    • DEIC
  • PAM Module
    • STFC, KIT









Important
We are working together
to make things compatible

That’s all
























In case I talked fast enough

Orpheus

https://orpheus.data.kit.edu

  • Gain deep insights
    • into everything

https://orpheus.data.kit.edu
























Motely-cue Architecture

KIT SSH-OIDC: Installation

  • Package installation:
    • Server: apt-get install motley-cue pam-ssh-oidc
    • Client: pip install mccli
  • Configuration:
    • PAM Module: /etc/pam.d/sshd
    • [Authorisation / Supported OPs: /etc/motley-cue/motley-cue.conf]
    • [Provisioning: /etc/motley-cue/feudal.conf]