Skip to content
Merged
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
14 changes: 14 additions & 0 deletions dsl/extdeps/access/posix.dag
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module extdeps.access.posix

import std.types { NonEmptyStr }
import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }

Expand Down Expand Up @@ -34,3 +35,16 @@ type FilePermissions {
ownership: FileOwnership
mode: FileMode
}

type PosixUser {
name: NonEmptyStr
uid: Int
gid: Int
}


data posix_root_uid: Int = 0

fn posix_user_is_root(user: PosixUser) -> Bool {
user.uid == posix_root_uid
}
63 changes: 63 additions & 0 deletions dsl/extdeps/bmc/access.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module extdeps.bmc.access

import extdeps.access.rbac { Permission, PermissionAssignment, RbacPolicy }
import extdeps.bmc.types {
RedfishAccountRole,
AccountRoleAdministrator,
AccountRoleOperator,
AccountRoleReadOnly,
redfish_account_role_wire,
RedfishPrivilege,
PrivilegeLogin,
PrivilegeConfigureManager,
PrivilegeConfigureUsers,
PrivilegeConfigureComponents,
PrivilegeConfigureSelf,
redfish_privilege_wire,
}
import std.types { NonEmptyStr }
import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }

data extdeps_external_authority_anchor: ExternalAuthority = ExternalAuthority {
uri: Uri {
scheme: Https
locator: "www.dmtf.org/standards/redfish"
}
}

data redfish_privilege_object: NonEmptyStr = "redfish"

fn redfish_privilege_permission(privilege: RedfishPrivilege) -> Permission {
Permission { operation: redfish_privilege_wire(p: privilege), object: redfish_privilege_object }
}

fn redfish_privilege_assignment(privilege: RedfishPrivilege, role: RedfishAccountRole) -> PermissionAssignment {
PermissionAssignment {
permission: redfish_privilege_permission(privilege: privilege),
role: redfish_account_role_wire(role: role),
}
}

data redfish_rbac_policy: RbacPolicy = RbacPolicy {
users: [],
roles: [
redfish_account_role_wire(role: AccountRoleAdministrator),
redfish_account_role_wire(role: AccountRoleOperator),
redfish_account_role_wire(role: AccountRoleReadOnly),
],
user_assignments: [],
permission_assignments: [
redfish_privilege_assignment(privilege: PrivilegeLogin, role: AccountRoleAdministrator),
redfish_privilege_assignment(privilege: PrivilegeConfigureManager, role: AccountRoleAdministrator),
redfish_privilege_assignment(privilege: PrivilegeConfigureUsers, role: AccountRoleAdministrator),
redfish_privilege_assignment(privilege: PrivilegeConfigureComponents, role: AccountRoleAdministrator),
redfish_privilege_assignment(privilege: PrivilegeConfigureSelf, role: AccountRoleAdministrator),
redfish_privilege_assignment(privilege: PrivilegeLogin, role: AccountRoleOperator),
redfish_privilege_assignment(privilege: PrivilegeConfigureComponents, role: AccountRoleOperator),
redfish_privilege_assignment(privilege: PrivilegeConfigureSelf, role: AccountRoleOperator),
redfish_privilege_assignment(privilege: PrivilegeLogin, role: AccountRoleReadOnly),
redfish_privilege_assignment(privilege: PrivilegeConfigureSelf, role: AccountRoleReadOnly),
],
role_hierarchy: [],
}
17 changes: 17 additions & 0 deletions dsl/extdeps/bmc/types.dag
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ type RedfishAccountRole =
| AccountRoleOperator
| AccountRoleReadOnly

type RedfishPrivilege =
PrivilegeLogin
| PrivilegeConfigureManager
| PrivilegeConfigureUsers
| PrivilegeConfigureComponents
| PrivilegeConfigureSelf

fn redfish_boot_target_wire(t: RedfishBootSourceOverrideTarget) -> NonEmptyStr {
match t {
BootTargetNone => "None"
Expand Down Expand Up @@ -153,3 +160,13 @@ fn redfish_account_role_wire(role: RedfishAccountRole) -> NonEmptyStr {
AccountRoleReadOnly => "ReadOnly"
}
}

fn redfish_privilege_wire(p: RedfishPrivilege) -> NonEmptyStr {
match p {
PrivilegeLogin => "Login"
PrivilegeConfigureManager => "ConfigureManager"
PrivilegeConfigureUsers => "ConfigureUsers"
PrivilegeConfigureComponents => "ConfigureComponents"
PrivilegeConfigureSelf => "ConfigureSelf"
}
}
31 changes: 31 additions & 0 deletions dsl/test/claim/access_layer_extension_witness_test.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module test.claim.access_layer_extension_witness

import std.types { NonEmptyStr, Bool, Int }
import extdeps.access.posix { PosixUser, posix_user_is_root }
import extdeps.access.rbac { RbacPolicy }
import extdeps.bmc.access { redfish_rbac_policy }
import extdeps.bmc.types { AccountRoleAdministrator, AccountRoleReadOnly, redfish_account_role_wire }

fn role_has_privilege(policy: RbacPolicy, role: NonEmptyStr, privilege: NonEmptyStr) -> Bool {
fold(policy.permission_assignments, init: false, f: fn(acc, pa) {
if acc { true }
else { pa.role == role && pa.permission.operation == privilege }
})
}

data root_user: PosixUser = { name: "root", uid: 0, gid: 0 }

data service_user: PosixUser = { name: "deploy", uid: 1000, gid: 1000 }

test fn posix_root_identification_holds() -> Bool {
posix_user_is_root(user: root_user) && (posix_user_is_root(user: service_user) == false)
}

test fn bmc_least_privilege_via_rbac_holds() -> Bool {
let admin = redfish_account_role_wire(role: AccountRoleAdministrator)
let reader = redfish_account_role_wire(role: AccountRoleReadOnly)
role_has_privilege(policy: redfish_rbac_policy, role: admin, privilege: "ConfigureUsers")
&& (role_has_privilege(policy: redfish_rbac_policy, role: reader, privilege: "ConfigureUsers") == false)
&& role_has_privilege(policy: redfish_rbac_policy, role: reader, privilege: "Login")
&& role_has_privilege(policy: redfish_rbac_policy, role: reader, privilege: "ConfigureSelf")
}