Marcus Hardt, Uros Stevanovic, Gabriel Zachmann

November 2020

Overview

Design Goals

Make the commandline greate again !!

Have an ssh-agent for OIDC

Initial Goal

  • Status Quo (~2018):
    • Copy-paste AT from web applications
  • How to obtain an Access Token (AT)
  • ATs are usually long strings (180-1200 characters)
  • Lifetime (~10min-1h) => requires frequent renewal

With time came requirements:

  • Manage and obtain OIDC tokens
  • Simplify user experience
    • Support/hide OAuth2/OIDC features
      • auth-code flow
      • device flow
      • scopes
      • audience
  • “Non-web” use cases:
    • Commandline
    • REST APIs
    • Non-interactive usage (e.g. from programs)
  • Use oidc in remote sessions
    • Agent-forwarding (just as as in ssh with agent-forwarding)
  • Security
    • Strong cryptography, careful implementation, security audits

Issues with OIDC

  • OIDC was designed for web-browser based applications

  • But we had non-web-(browser) use-cases:

    • Applications and REST interfaces with federated identification
      • Delegated authentication (Service acts on users behalf, e.g. get data from yet another server)
      • Data management (webDav/OIDC, remote job/container/vm submission)
      • Batch jobs (including long-running jobs)
    • Development/debugging, interactive usage on the commandline

Technicalities

Non-nerds may take a rest

OpenID Connect (OIDC) Recap

  • Authentication protocol on top of OAuth2
  • Three different tokens:
    • Access Token (AT): for authorisation with a service / resource (OAuth2 and OIDC)
    • Refresh Token (RT): to obtain additional access tokens (OAuth2 and OIDC)
    • ID Token: contains user information (only OIDC)
  • Several flows to obtain the tokens:
    • Authorisation code flow (standard web flow, e.g. “Sign in with Google”)
    • Implicit flow (mainly for Single-Page-Applications, usage discouraged)
    • Refresh flow (to obtain additional ATs from a RT)
    • Device flow (for input constrained devices (e.g. TVs))
    • Dynamic client registration flow
    • Token refresh flow
    • Continuously growing number

Client registration

  • Client registration is rather complex, and depends on OIDC Provider
  • Many options for client registration:
    • Dynamic client registration (default)
      • oidc-agent self-registers himself as a new client
      • depending on the provider, this may require an initial token
      • not supported by all providers
      • Examples: IAM, HBP (protected)
    • Public client (fallback)
      • oidc-agent comes with a public client for all providers that support it
        • pre-registered by us with the correct configuration parameters and approved by the provider
      • not supported by all providers
      • Examples: EGI, Google, IAM, HBP, Elixir, HDF, KIT
    • Manual client registration (fallback of fallback)
      • user registers a client manually (e.g. through a web interface)
      • user has to specify the correct configuration parameters
      • Examples: eduTEAMS, B2Access

Non-nerds:

wake up now

oidc-agent

Relationships

Separated at birth?

ssh-agent <=> oidc-agent

  • ssh-agent => oidc-agent: Daemon
    • Communicate with OpenID Provider
    • Interface to clients
    • Store secrets in (encrypted!) memory (RefreshToken, client_secret, …)
  • ssh-keygen => oidc-gen:
    • Register OIDC client and initialise configuration
    • Pass encrypted data to agent
  • ssh-add => oidc-add:
    • Prompt for password and load secrets into agent
  • ssh => oidc-token:
    • Obtain and return an access token
  • In addition to ssh-agent:
    • oidc-keychain: enables using oidc-agent between sessions
    • oidc-agent-server: central version of oidc-agent that can run on a server
      • Useful for remote processes to refresh their AccessTokens

Advanced features

  • Xsession integration to autorun at startup
  • Configuration auto-load when necessary (password-prompting, even when used in a shell script)
  • Agent forwarding:
    • ssh to remote hosts
    • private material (e.g. refresh token) never leaves the local machine
  • Support for debian-, redhat-, arch-, gentoo- and mac-os- based systems
  • Works with many OIDC providers:
    • EGI-Checkin
    • Indigo IAM
    • eduTeams/satosa
    • Keycloak
    • Human-Brain
    • B2Access
    • Google
  • Supports multiple profiles (user accounts in different OIDC providers)
  • Supports setting the Audience Claim "aud"

Security hightlights

  • All sensitive information on disk is encrypted (using libsodium)
  • Everything (sensitive) in RAM is obfuscated (dynamic random passwords)
  • Agent can be locked
    • While locked all (sensitive) information is encrypted
    • No operations allowed while locked
  • Privilege separation
    • Enforcement via seccomp available (off by default)
    • Separate processes for disk- and network access
  • Keep the user from stupid moves
    • unlike ssh we do allow them (if you RTFM)

Architecture

Using the agent

General Mode of operation:

  1. Create a new account configuration (with the OIDC-Provider)
    • Once in your life (once per year, in case of EGI)
    • Requires a bit of doc-reading
    • Stored on the users disk
  2. Load account configuration
    • Once per XSession (~5 times per year)
    • Requires password entering
  3. Get Access Tokens
    • As often as you like
    • Not a single password

1. Account Creation

  • Generating a new account configuration:
    • General: $ oidc-gen <shortname>
    • EGI-Checkin
      • $ oidc-gen --pub egi --iss=https://aai.egi.eu/oidc/ --scope-max
      • $ oidc-gen --pub egi --iss=https://aai.egi.eu/oidc/ --scope "eduperson_entitlement eduperson_scoped_affiliation eduperson_unique_id email offline_access openid profile eduperson_assurance"
    • Google
      • $ oidc-gen --pub google
    • IAM
      • $ oidc-gen iam
    • Any other provider:

2. Load Account Configuration

  • General: $ oidc-add <shortname>
  • EGI: $ oidc-add egi

3. Get Access Tokens

  • Obtaining access tokens from the agent:
    • Print the AT for the requested account configuration
      • $ oidc-token <shortname>
    • Integrate the oidc-token call into another command, e.g. curl call
      • $ curl -H “Authorization: Bearer `oidc-token <shortname>`” https://…
    • Get information that’s inside the token (and at the userinfo endopint):
      • $ flaat-userinfo `oidc-token <shortname>`

Short demo

  • Pre registered client with EGI Check-in
    1. Load a configuration
    1. Get a token
    1. Log in to a remote host
    1. Get token there

$ flaat-userinfo `oidc-token <shortname>`

Information stored inside the access token:

{
    "body": {
        "azp": "oidc-agent",
        "exp": 1603820899,
        "iat": 1603817299,
        "iss": "https://aai.egi.eu/oidc/",
        "jti": "db9c79be-25a4-40f5-a448-20e5b00c911b",
        "sub": "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu"
    },
    "header": {
        "alg": "RS256",
        "kid": "oidc"
    },
    "signature": "Xs4AhwmSk1OXJcH7EKlOhuQgmOmCoqqejj6_Mm5b3WwvaGYf8eg_DfprNQTqiakjJWrnXJraiHoEwzhRZSD0YchtPvN7p7FPqabw3rGCVsJ4NA6zZloEXNrdcE-cTNdZqi8AoVmGJcLMB9IB-X_wwnSCBROwoFlJQmLhOy3P-BKDNOJYfKb8MBM4nUsPp0owEH11mzes2DyX2VzoP62_GRSZ-Fx6EJA_hXKqhUAJUH0KLKAOlzXnNxz2ZGLZzr2pzOeErSsU2iE_pcUvaxR2a-1NGvdY7hXqUSxSfax9d9BGsRgeNx5k3cQ_LgE2-yLDAQXf-oicrDmiDomCpWU1bw"
}

Information retrieved from userinfo endpoint:

{
    "acr": "https://aai.egi.eu/LoA#Substantial",
    "edu_person_scoped_affiliations": [
        "faculty@KIT"
    ],
    "eduperson_assurance": [
        "https://aai.egi.eu/LoA#Substantial"
    ],
    "eduperson_scoped_affiliation": [
        "faculty@KIT"
    ],
    "eduperson_unique_id": "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu",
    "email": "hardt@kit.edu",
    "family_name": "Hardt",
    "given_name": "Marcus",
    "name": "Marcus Hardt",
    "preferred_username": "mhardt",
    "sub": "d7a53cbe3e966c53ac64fde7355956560282158ecac8f3d2c770b474862f4756@egi.eu",
    "eduperson_entitlement": [
        "urn:mace:egi.eu:group:covid19.eosc-synergy.eu:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:covid19.eosc-synergy.eu:admins:role=owner#aai.egi.eu",
        "urn:mace:egi.eu:group:covid19.eosc-synergy.eu:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:covid19.eosc-synergy.eu:role=vm_operator#aai.egi.eu",
        "urn:mace:egi.eu:group:eosc-synergy.eu:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group: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:eosc-synergy.eu:role=vm_operator#aai.egi.eu",
        "urn:mace:egi.eu:group:goc.egi.eu:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:goc.egi.eu:role=vm_operator#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:admins:role=owner#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:perfmon.m.d.k.e:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:perfmon.m.d.k.e:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:mteam.data.kit.edu:role=vm_operator#aai.egi.eu",
        "urn:mace:egi.eu:group:o3as.data.kit.edu:admins:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:o3as.data.kit.edu:admins:role=owner#aai.egi.eu",
        "urn:mace:egi.eu:group:o3as.data.kit.edu:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:o3as.data.kit.edu:role=vm_operator#aai.egi.eu",
        "urn:mace:egi.eu:group:registry:perfmon:role=member#aai.egi.eu",
        "urn:mace:egi.eu:group:registry:perfmon:role=owner#aai.egi.eu",
        "urn:mace:egi.eu:aai.egi.eu:admins:member@covid19.eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:admins:member@eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:admins:member@mteam.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:admins:member@o3as.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:admins:owner@covid19.eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:admins:owner@eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:admins:owner@mteam.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:admins:owner@o3as.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:member@covid19.eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:member@eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:member@goc.egi.eu",
        "urn:mace:egi.eu:aai.egi.eu:member@mteam.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:member@o3as.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:member@perfmon",
        "urn:mace:egi.eu:aai.egi.eu:member@perfmon.m.d.k.e",
        "urn:mace:egi.eu:aai.egi.eu:owner@perfmon",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@covid19.eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@eosc-synergy.eu",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@goc.egi.eu",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@mteam.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@o3as.data.kit.edu",
        "urn:mace:egi.eu:aai.egi.eu:vm_operator@perfmon.m.d.k.e"
    ]
}

Application integration

  • Applications that need an AT can interface with the agent:
    • More user friendly: just provide the shortname (or issuer URL)
    • Applications can assume valid ATs
      • While content of environment variable would expire at some point
    • Libraries available for c, go, and python
  • Applications that use oidc-agent:
    • wattson
    • feudalSSH
    • unicore command line client
    • rclone file transfer tool
  • Mentions of oidc-agent in docs:
    • Nordugrid ARC-6

Summing up

Compatibilty

  • oidc-agent was tested to work with the following providers:
    • Eudat / B2Access (Unity)
    • eduTEAMS
    • EGI-Checkin
    • Elixir
    • Google
    • Helmholtz Data Federation
    • Human Brain Project
    • IAM (Indigo, Deep, Extreme, WLCG)
    • KIT
  • It’s easy to get oidc-agent to work with any OpenID Provider. In case of problems, please contact us: oidc-agent-contact@lists.kit.edu

Future Work

  • Linux Distro Integration:
    • Debian
    • EPEL
  • my-token: support the last unsolved use-case:
    • Token Renewal Service
    • Support for long-running jobs
    • Fine grained access control
    • Available: some time next year

oidc-agent - Summary