Skip to content

Local environment

A Local environment is executed on the host itself (same host where Bifröst is running).

Currently, we support different variants provided by the host operating system which is executing the environment.

Type identifier is local.

Linux

The Linux variant is only supported by Linux based operating systems.

It can run as the Bifröst user itself, but can also impersonate another user.

Note

If impersonating another user Bifröst than is running at, root permissions are required.

User requirement

Users have to fulfill the defined requirements (name, displayName, uid, group, groups, shell, homeDir and skel).

If a user does not fulfill this requirement he is not eligible for the environment. The environment can create a user (createIfAbsent = true) or even update an existing one (updateIfDifferent = true) to match this requirement. This does not make a lot of sense for local users; but for users authorized via OIDC - which usually do not exist locally.

See the evaluation matrix of createIfAbsent and updateIfDifferent to see the actual reactions of the local environment per users requirement evaluation state.

Configuration

type

Environment Type = "local"

Has to be set to local to enable the local environment.

loginAllowed

Has to be true (after being evaluated) that the user is allowed to use this environment.

Examples
  1. Require that the existing local user has the group ssh:

    1
    2
    3
    4
    5
    loginAllowed: |
       {{ or
           (.authorization.user.group.name | eq "ssh" )
           (.authorization.user.groups     | firstMatching `{{.name | eq "ssh"}}`)
       }}
    

  2. Require that the user authorized via OIDC has in the group my-great-group-uuid and the tenant ID (tid) in this OIDC ID token:

    1
    2
    3
    4
    5
    loginAllowed: |
       {{ and
          (.authorization.idToken.groups | has "my-great-group-uuid")
          (.authorization.idToken.tid    | eq  "my-great-tenant-uuid")
       }}
    

name

The username the user should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. Use the name of the local user:
    1
    name: "{{.authorization.user.name}}"
    
  2. Use the email address of the user authorized via OIDC:
    1
    name: "{{.authorization.idToken.email}}"
    
  3. Always use foobar:
    1
    name: "foobar"
    

displayName

The display name (or title or GECOS) the user should have.

Examples
  1. In case of local user should be never be defined.
  2. Use the email address of the user authorized via OIDC:
    1
    displayName: "{{.authorization.idToken.name}}"
    
  3. Always use Foobar:
    1
    displayName: "Foobar"
    

uid

The UID (user identifier) the user should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. Use the name of the local user:
    1
    uid: "{{.authorization.user.uid}}"
    
  2. In case of users authorized via OIDC this should usually not be defined.
  3. Always use 123:
    1
    uid: 123
    

group

The primary group the user should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. If local user is used, this should usually not be defined.
  2. Assign always group with name oidc in case of users authorized via OIDC:
    1
    2
    group:
      name: "oidc"
    

groups

Array<Group>

The groups (do not confuse with the primary group) the user should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. If local user is used, this should usually not be defined.
  2. Assign always group with name oidc in case of users authorized via OIDC:
    1
    2
    groups:
      - name: "oidc"
    

shell

The shell the user should have. If not defined means this requirement won'T be evaluated or applied (in case of creation/modification of a user).

homeDir

String Template<Authorization> = "/home/<user.name>"

The home directory the user should have. If not defined means this requirement won't be evaluated or applied (in case of creation/modification of a user).

skel

Is a directory on the Bifröst hosts where a user that needs to be created, will receive its initial files of its home directory from (= user's home skeleton/template directory).

createIfAbsent

Will create the local user if it does not exist to match the provided requirements (see below). If this property is false the user has to exist, otherwise the execution will fail and the connection will be closed immediately.

This property (together with updateIfDifferent) should be true if you're using authorizations like OIDC, where the user is not expected to exist locally, and you don't want to create each user individually.

Evaluation
createIfAbsent = false = true
Exists and matches Accepted Accepted
Exists, but does not match Does not apply Does not apply
Does not exist Rejected Created and accepted

updateIfDifferent

If an existing user does not match the provided requirements (see below) and this property is true, this user will be adjusted to match the requirements.

This property (together with createIfAbsent) should be true if you're using authorizations like OIDC, where the user is not expected to exist locally and you don't want to create each user individually.

Evaluation
updateIfDifferent = false = true
Exists and matches Accepted Accepted
Exists, but does not match Rejected Modified and accepted
Does not exist Does not apply Does not apply

banner

Will be displayed to the user upon connection to its environment.

Examples
  1. If local user is used, show its name in a message:
    1
    banner: "Hello, {{.authorization.user.name}}!\n"
    
  2. If users authorized via OIDC is used, show its name in a message:
    1
    banner: "Hello, {{.authorization.idToken.name}}!\n"
    

portForwardingAllowed

If true, users are allowed to use SSH's port forwarding mechanism.

dispose

Defines what should happen if an environment will be disposed.

Examples

  1. Use existing UNIX user:
    1
    2
    type: local
    name: "{{.authorization.user.name}}"
    
  2. OIDC - create/modify user if absent/different and cleanup automatically:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    type: local
    
    ## Ensure users get created/modified if absent/different...
    createIfAbsent: true
    updateIfDifferent: true
    
    ## Use the email address of the OIDC's ID token
    name: "{{.authorization.idToken.email}}"
    
    ## Use the display name of the OIDC's ID token
    displayName: "{{.authorization.idToken.name}}"
    
    groups:
      ## Ensure user has always the group `oidc` assigned for better access control
      ## on the host itself.
      - name: oidc
    
    shell: "/bin/bash"
    
    ## Only allow login if the OIDC's groups has "my-great-group-uuid"
    ## ...and the tid (tenant ID) is "my-great-tenant-uuid"
    loginAllowed: |
        {{ and
          (.authorization.idToken.groups | has "my-great-group-uuid")
          (.authorization.idToken.tid    | eq  "my-great-tenant-uuid")
        }}
    

Group

name

The name the group should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. In case of local user this should usually not be used.
  2. Use the email address of the user authorized via OIDC always set the name oidc:
    1
    name: "oidc"
    

gid

The GID (group identifier) the group should have. Empty means this requirement won't be evaluated or applied (in case of creation/modification of a user).

Examples
  1. Always use 123
    1
    name: 123
    

Dispose

Defines the behavior of an environment on disposal (cleanup).

deleteManagedUser

If true the environment will also delete users, created/managed by it. Usually, if createIfAbsent and updateIfDifferent is both false this has no effect.

deleteManagedUserHomeDir

In combination with deleteManagedUser, if true the environment will also delete the user's home directory.

killManagedUserProcesses

In combination with deleteManagedUser, if true the environment will also kill all user's running processes.

Windows

The Windows variant is only supported by Windows 7+ based operating systems.

Warning

In contrast to the Linux version this variant CANNOT impersonate. As a consequence, each user session always executes as the user the Bifröst process itself runs with.

1
Impersonating on a Windows machine requires either full credentials (password) or another running process the session tokens can be cloned from. As both conflicts how we intend Bifröst to work, both solutions leave a lot of use-cases behind. Since it is very "hacky", we decided to stick with the simple approach.

Configuration

type

Environment Type = "local"

Has to be set to local to enable the local environment.

loginAllowed

Has to be true (after being evaluated) that the user is allowed to use this environment.

Examples
  1. Require that the user authorized via OIDC has in the group my-great-group-uuid and the tenant ID (tid) in this OIDC ID token:
    1
    2
    3
    4
    5
    loginAllowed: |
       {{ and
          (.authorization.idToken.groups | has "my-great-group-uuid")
          (.authorization.idToken.tid    | eq  "my-great-tenant-uuid")
       }}
    

banner

Will be displayed to the user upon connection to its environment.

Examples
  1. If users authorized via OIDC is used, show its name in a message:
    1
    banner: "Hello, {{.authorization.idToken.name}}!\n"
    

shellCommand

["C:\\WINDOWS\\system32\\cmd.exe"]

The shell which is used to execute the user's session.

execCommandPrefix

["C:\\WINDOWS\\system32\\cmd.exe", "/C"]

The executor command prefix which is used when a user executes a command instead of executing into a shell.

If the user will execute ssh foo@bar.com echo "bar" on the host C:\WINDOWS\system32\cmd.exe /C 'echo "bar"' will be executed.

directory

"<working directory of Bifröst>"

The working directory where the command will be executed in.

portForwardingAllowed

If true, users are allowed to use SSH's port forwarding mechanism.

Examples

  1. Simple:
    1
    type: local
    
  2. OIDC:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    type: local
    
    ## Use the PowerShell Core without banner as Shell
    shellCommand: ["pwsh.exe", "-NoLogo"]
    directory: "C:\\my\\home"
    
    ## Only allow login if the OIDC's groups has "my-great-group-uuid"
    ## ...and the tid (tenant ID) is "my-great-tenant-uuid"
    loginAllowed: |
        {{ and
          (.authorization.idToken.groups | has "my-great-group-uuid")
          (.authorization.idToken.tid    | eq  "my-great-tenant-uuid")
        }}
    

Compatibility

linux/generic linux/extended windows/generic
* * *