Welcome to FabAccess documentation!¶
FabAccess is still in a state of development and has no stable Release.
So there is no stability and backward compatibility between the versions. Feel free to help us testing our software stack but not expect a full functional software. We will inform you about breaking changes over our Zulip. Please subscript to it to stay up to date, because the server and client can get incompatible.
Install FabAccess¶
FabAccess has an Server an Client structure.
So the Server and the Client must be installed seperatly.
Install Server¶
The Server can be installed over two recommended ways.
The easiest way is to use Docker with Docker-Compose.
To add youre own Plugins and Software you should use the Build way.
Build Server from Source¶
E.g. in a proxmox- or lxc-container.
Install Dependencies¶
Ubuntu / Debian¶
sudo apt update && sudo apt upgrade
sudo apt install curl && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt install libgsasl7-dev libssl-dev build-essential
sudo apt install git cmake clang capnproto
Arch Linux¶
sudo pacman -Syu
sudo pacman -S make cmake clang gsasl
sudo pacman -S git rust capnproto
CentOS¶
sudo yum update
sudo yum install curl && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo yum install epel-release && sudo yum install capnproto
sudo yum install https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm && sudo yum install git
sudo yum install centos-release-scl && yum install llvm-toolset-7 && scl enable llvm-toolset-7 bash
(Change bash to youre shell)sudo yum install gcc-c++ libgsasl-devel openssl-devel cmake
FreeBSD¶
TODO
Build BFFH¶
Start new terminal - Rustup will not update path while install
git clone https://gitlab.com/fabinfra/fabaccess/bffh.git --recursive
cd bffh
- (Optional)
git checkout development && git submodule update --remote
(Changedevelopment
to wanted branch) cargo build --release
Run Server with Docker¶
Docker Image can not run on armv6 (Raspberry Pi 1 or Raspberry Pi Zero)
Install Docker
On Raspberry Pi: https://phoenixnap.com/kb/docker-on-raspberry-pi
Install Docker-Compose
On Raspberry Pi: https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo
Get Docker-Compose Files
git clone https://gitlab.com/fabinfra/fabaccess/dockercompose.git fabaccess-server
The Dockerfile is in the root directory of the main repo docker-compose.yml is available in a seperate git repo
Edit config files in
config
folder to tasteStart Server with
docker-compose up -d
To make it eaysier to apply youre changes in your config and keep the dockercompose uptodate, you should “fork” this respository.
Get Server Logs: docker-compose logs
Install Client¶
The Client communicates with the server over an API. So you can use any Client that support the current API Version of the Server.
- We provide an Native Client for the following Platforms:
- Android
- iOS
- UWP
For MacOS and Linux(GTK) we will provide a Client later in our Development.
Build Client from Source¶
On Windows¶
Install Visual Studio 2019 download Visual Studio
- with Xamarin
- with UWP
- with .NET Desktop
Install GTKSharp for Windows download GTKSharp
Install capnproto
3.1 If you have Chocolatey installed
$ choco install capnproto
3.2 else you can download it from here and add it to your PATH
Clone Borepin download Borepin
Load Borepin
Build Borepin
If Step 5. Build Borepin is failing because of GTKSharp, it could help to restart your PC.
Build GTK Project¶
Install mono download mono
Install mono, gtk-sharp, msbuild, nuget, capnproto 1.1 Debian based
$ apt install mono-complete, gtk-sharp2, libcanberra-gtk-module, nuget, capnproto, git
1.2 ArchLinux based
$ pacman -S mono, mono-msbuild, gtk-sharp-2, nuget, capnproto
Update NuGet
$ nuget update -self
Clone Borepin
$ git clone https://gitlab.com/fabinfra/fabaccess/client.git --recurse-submodules
Build Borepin
$ cd client $ nuget restore $ msbuild -t:Borepin_GTK
Run Borepin
$ mono ./Borepin/Borepin.GTK/bin/Debug/Borepin.GTK.exe
You can also use Rider or monodevelop as an IDE for development on Borepin
macOS / iOS¶
Install Visual Studio for Mac
Install capnproto If you install capnp with Homebrew you may have to symlink the capnp binary into ‘/usr/local/bin’, or bring it into your PATH another way.
Clone Borepin
$ git clone https://gitlab.com/fabinfra/fabaccess/client.git --recurse-submodules
Open in Visual Studio
Build
Installation Example for FabAccess Enviroment¶
Install on Ubuntu for “Dummies”¶
This description is how to compile and set up Diflouroborane on Ubuntu 20.04.3 LTS clean install. Other releases or distros might work as well. The process is quite lengthy but at the end you will have a FabAccess running to you needs. … as I said: for complete dummies, if someone finds a better solution, please post suggestions on: https://fabaccess.zulipchat.com/#narrow/stream/255963-General/topic/Demo
- Get your system up-to-date
sudo apt-get update && sudo apt-get upgrade
- Get rustup
sudo apt install curl
curl --proto 'https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
restart the console - Get capnproto, gsasl and git
sudo apt-get install gsasl
sudo apt-get install capnproto
sudo apt install git
- Create a target directory for BFFH
there might be better places compared to where I created it, but it works…
mkdir BFFH
cd BFFH
- Clone the Diflouroborane repository
git clone https://gitlab.com/fabinfra/fabaccess/bffh --recursive --branch main
- For compiling some dependencies were missing on Ubuntu
git submodule update --init
sudo apt install libgsasl7-dev
sudo apt install cmake
sudo apt install libclang-dev
sudo apt install libssl-dev
- Open the subdirectory and start compiling
cd bffh
cargo build --release
if the compiler prompts somthing like “error: linker ‘cc’ not found”:sudo apt install build-essential
cargo build --release
- Copy the configuration files (best done with the GUI filemanager of Ubuntu) copy files from “bffh/examples” paste them into “bffh/target/release/examples”
- Install mosquitto MQTT broker
Diflouroborane uses mosquitto MQTT broker to communicate with the Shellies. Starting from Ubuntu version 18.04, Mosquitto is already inside the official repositories.
sudo apt update -y && sudo apt install mosquitto mosquitto-clients -y
- Configuring mosquitto broker for some reason, starting with version 2.x mosquitto does not allow external communication via the broker per default. This needs to be changed via a config file:
- Stop mosquitto
sudo systemctl stop mosquitto
- Change into the “etc/mosquitto/” directory (lots of
cd ..
thencd etc/mosquitto
) - Edit the configuration fil:
sudo nano mosquitto.conf
add:listener 1883
allow_anonymous true
Save (Strg-O) and close (Strg-X) - Enable mosquitto to start at each start of the system
sudo systemctl enable --now mosquitto
- Restart the system.
The BFFH-server can be found at the /target/release folder. Prior to starting the system you need to copy the files from bffh/examples
to bffh/target/release/examples
This ist best done by using the GUI filemanager.
To get at least minimum functionality the bffh.dhall should be modified. The lines:
-- , init_connections = [] : List { machine : Text, initiator : Text }
, init_connections = [{ machine = "Testmachine", initiator = "Initiator" }]
, initiators = --{=}
{ Initiator = { module = "Dummy", params = { uid = "Testuser" } } }
should be modified to:
, init_connections = [] : List { machine : Text, initiator : Text }
--, init_connections = [{ machine = "Testmachine", initiator = "Initiator" }]
, initiators = {=}
--{ Initiator = { module = "Dummy", params = { uid = "Testuser" } } }
To start the server change into the directory by using cd target/release
and using:
./bffhd -c examples/bffh.dhall --load examples/users.toml
an then:
./bffhd -c examples/bffh.dhall
BUT prior to starting bffh, you should first configure the bffh.dhall file (see the “Use FabAcess” section).
Configure FabAccess¶
To run FabAccess you have to configure the Server(BFFH). And add your Machines, Actors and Initiators.
In the current state of FabAccess we will no support database migration so all persistent data are in configuration files.
bffh.dhall¶
BFFH uses DHALL for Config-File structure BFFH uses RBAC for access control
BFFH Config is in bffh.dhall
file.
General BFFH Config¶
listens
¶
Contains the Addresses BFFH is listen for Connection for the API
Default Port for BFFH is 59661
Example:
listens =
[
{ address = "127.0.0.1", port = Some 59661 }
]
mqtt_url
¶
Contains the Address for the MQTT Server BFFH connects to.
The Address has the format <protocol>://[user]:[password]@<server>:[port]
protocol
is required and can be one of:mqtt
,tcp
,mqtts
,ssl
user
andpassword
are optionalserver
is required and can be an ip address or a hostnameport
is optional
Example:
mqtt_url = "tcp://localhost:1883"
db_path
¶
Contains the Path for the internal Database BFFH uses.
BFFH will create two files: <db_path>
and <db_path>-lock
.
Make sure that BFFH has write access in the relevant directory
Example:
db_path = "/tmp/bffh"
Permissions¶
BFFH uses a Path-style string as permission format, separated by “.”.
So for example this.is.a.permission
consists of the parts this
, is
, a
and permission
.
When requireing permissions, such as in machines you always need to give an exact permission, so for example test.write
.
When granting permissions, such as in roles you can either give an exact permission or you can use the two wildcards *
and +
.
These wildcards behave similar to regex or bash wildcards:
*
grants all permissions in that subtree. So,perms.read.*
will match for any of:perms.read
perms.read.machineA
perms.read.machineB
perms.read.machineC.manage
+
grants all permissions below that one. So,perms.read.+
will match for any of:perms.read.machineA
perms.read.machineB
perms.read.machineC.manage
- but not
perms.read
Wildcards are probably most useful if you group you machines around them, e.g. your 3D-printers and your one bandsaw require:
- Write permissions
machines.printers.write.prusa.sl1
machines.printers.write.prusa.i3
machines.printers.write.anycubic
machines.bandsaws.write.bandsaw1
- Manage permissions
machines.printers.manage.prusa.sl1
machines.printers.manage.prusa.i3
machines.printers.manage.anycubic
machines.bandsaws.manage.bandsaw1
- Admin permissions
machines.printers
- For all printers
machines.bandsaws
- For all bandsaws
And you then give roles permissions like so:
- Use any 3D printer:
machines.printers.write.+
- Only allow use of the “cheap” printers
machines.printers.write.anycubic.*
machines.printers.write.prusa.i3
- Allow managing of printers:
machines.printers.+
- Allow administrating printers:
machines.printers.*
This way if you buy a different anycubic and split the permissions to e.g.
machines.printers.write.anycubic.i3
machines.printers.write.anycubic.megax
It still works out.
Machine Config¶
machines
¶
Contains list of machines
Machines have different perission levels to interact with:
- disclose: User can see the machine in machine list
- read: User can read information about the machine and there state
- write: User can use the machine
- manage: User can interact with the machine as Manager (Check, ForceFree, ForceTransfer)
Each machine must have an ID to reference the machine in other part of this config or over the API. And each machine must have a name.
Optional Information¶
To provide more information about the machine you can add it to the description or provid an external wiki link. Both attributes are only optional and do not need to be set.
Example:
machines =
{
machine123 =
{
name = "Testmachine",
description = Some "A test machine",
wiki = "https://someurl"
disclose = "lab.test.read",
read = "lab.test.read",
write = "lab.test.write",
manage = "lab.test.admin"
}
}
“machine123” is in this case the “Machine-ID”
Roles Config¶
The roles are configured in the bffh.dhall. If the file “roles.toml” is existing in the directory, it can be deleted and can’t be used to manage roles.
roles
¶
Contains list of roles
Roles have a list of permission and can be inherited. Permission can be wildcard in permission list.
Example:
roles =
{
testrole =
{
permissions = [ "lab.test.*" ]
},
somerole =
{
parents = ["testparent"],
permissions = [ "lab.some.admin" ]
},
testparent =
{
permissions =
[
"lab.some.write",
"lab.some.read",
"lab.some.disclose"
]
}
}
Actors Config¶
actors
¶
Contains list of actors Actors are defined by a module and one or more paramters
Currenty supported actors:
Shelly Actor
¶
This actor connects BFFH over an MQTT-Server to an shelly device.
You need to set the topic
parameter of the Shelly to the Shelly specific MQTT-Topic.
Example:
actors =
{
Shelly_123 =
{
module = "Shelly",
params =
{
topic = "shellyplug-s-123456"
}
}
}
“Shelly_123” is in this case the “Actor-ID”.
Process Actor
¶
This actor makes it possible for you to connect your own Devices to BFFH.
cmd
= Path of executable
args
= Arguments for executable
Example:
actors =
{
Bash =
{
module = "Process", params =
{
cmd = "./examples/actor.sh",
args = "your ad could be here"
}
}
}
actor_connections
¶
Connects the actor with a machine A machine can have multiple actors
Use the “Machine-ID” and “Actor-ID”. Example:
actor_connections =
[
{ machine = "Testmachine", actor = "Shelly_1234" },
{ machine = "Another", actor = "Bash" },
{ machine = "Yetmore", actor = "Bash2" }
]
user.toml¶
This configuration is located under /etc/bffh
.
Here the users, there Password, roles and cardkeys are stored.
Roles are defined in the bffh.dhall configuration. The Docker-compose Repository has a good example
[Admin1]
roles = ["Admin"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[Admin2]
roles = ["Admin"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ManagerA1]
roles = ["ManageA", "UseA", "ReadA", "DiscloseA"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ManagerA2]
roles = ["ManageA", "UseA", "ReadA", "DiscloseA"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ManagerB1]
roles = ["ManageB", "UseB", "ReadB", "DiscloseB"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ManagerB2]
roles = ["ManageB", "UseB", "ReadB", "DiscloseB"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
[ManagerC1]
roles = ["ManageC", "UseC", "ReadC", "DiscloseC"]
passwd = "secret"
noot = "noot!"
cardkey = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Configure BFFH Log¶
BFFH’s log level can be set via the environment variables or via bffh.dhall.
BFFH_LOG=debug
Supported levels are:
trace
debug
warn
info
error
Default Permissions¶
BFFH has some standard permissions to assign to management and admin rights.
UserSystem¶
bffh.users.manage
- Get ManageInterface in UserSystem (Access UserList)
User¶
bffh.users.info
- Get InfoInterface for every User (Access UserInfos of other accounts)bffh.users.admin
- Get AdminInterface for every User (Add/Remove Users, Reset Passwords)
Use FabAccess¶
FabAccess is highly customisable so you can use FabAccess the way you like to.
But to explain our Features we will documentated some best Practices.
QR-Codes on Machines¶
To imporve the selection of the right machine for youre users you can apply a QR-Code label on the machine.
The QR-Code must have the following content:
urn:fabaccess:resource:{machine id}
FabAccess Setup - Step By Step¶
This document provides a step by step Instruction on how to get FabAcess running. At the end of this description you will have:
- 1 or more Shellies registered to you system
- 1 or more users registered to your system
- QR-Codes generated to acess a machine
- 1 Shelly configured as a door-opener
- 1 Shelly configured to identify if a machine is just switched on or realy running (TO-DO)
Step 1 Installing the BFFH-Server
there are multiple ways to install the BFFH server. This can bei either done via
- docker - see docker installation document
- installing from source - see installing from source documentation
- installing on Ubuntu for dummies
Step 2 Installing the FabAccess App
get the App via Apple Store or Google Apps.
Step 3 Connect the App and the Server
First you need to find the IP of the server. This can be done by typing
ip a
on the console of the system where the BFFH-Server is running. Use the adress listed under BROADCAST.
Start the server. If you are using the docker, this is done by using
docker-compose up -d
.
If you compiled the server on your system this is done by entering
./diflouroborane -c examples/bffh.dhall --load examples
and then
./diflouroborane -c examples/bffh.dhall
.
You will see some debug information, with probably some warnings.
Open the App. You will be asked to connect to a Host. Tap “DEMO HOST ADRESS” and change the IP to the IP of your Server, do not change the port number (everything after the IP. This should look like 192.168.1.15:59661
).
Tap “SELECT HOST”.
You will be asked to sign in. For Version 0.2 only the Option “LOGIN WITH PASSWORD” ist available. Use Testuser
and the passwort secret
to log in.
You will find an overview of the installed machines including the option “SCAN QR-CODE”. Next step is setting up you machines so they can be switched on an off.
Step 4 Prepare your Shellies
as long as your Shelly has not been given the credentials for a WLAN, it will create an access point (AP) for configuration when connected to the supply voltage. This AP will appear in your list of WLAN.
Connect to this Shelly-AP and connect to 192.168.33.1
in your browser. A configuration page should appear.
If your Shelly is already connected to your WLAN, you must find the assigned IP-Adress (e.g. by looking into your router). Enter this IP Adress in your browser and you will get the configuration page.
Shelly MQTT Client setup
goto “Internet & Security” -> “Advanced - Developer Settings”
enable “MQTT”
enter the IP-Adress from your Server in the field “IP-Adress”
As we did not define MQTT credentials in mosquitto yet, no creadentials need to be filled in.
To find the “ID” of your Shelly activate “Use custom MQTT prefix” (but do not change it!). This should be somthing like:
shelly1-123456789ABC
for a Shelly 1
shelly1pm-123456
for a Shelly 1PM
note this ID for later
- save
- re-check the settings!
Shelly WLAN Client setup
goto “Internet & Security” -> “WIFI MODE - CLIENT” Set WLAN Credentials
Adding a Shelly to your server To understand the underlaying concept of actors and machines, please see the “configuration part” of the documentation. Four our example we will assume we have one actor (shelly) per machine.
Tip
Prior to modifying the configuration files the proper working of the MQTT broker should be tested. To test the broker it is the best to use a second (linux) computer with a different IP adress. To test if the broker allows access from an external IP address open a MQTT subscriber on the second computer by typing
mosquitto_sub -h 192.168.1.15 -t /test/topic
(change the IP adress to the adress of your server).
Use
mosquitto_pub -h localhost -t /test/topic -m "Hallo from BFFH-Server!"
to send a message to the other computer. If the message appears, everything is ok. When not, this should be first solved, as a connection to the shellies will not be possible this way.
If you are interested in communication between the shellies and the BFFH-Server you can use
mosquitto_sub -h 192.168.1.15 -t shellies/#
(change the IP adress to your needs). You will see some values popping op from time to time.
Configure Diflouroborane
Open the file “bffh.dhall” in the GUI Editor (just by double-clicking it) or use nano bffh.dhall
in your console.
Link the server to the MQTT-broker
find the line which starts with , listens
. You will find three lines stating addresses. The third address needs to be changed to the adress of your MQTT broker (most likely the IP adress of your BFFH server)
First you have to make your “actors” (in our case the Shellies) know to the system.
Go to the line where it starts with , actors =
and after the {
you can enter your Shelly with
shelly1-123456789ABC = { module = "Shelly", params = {=}}
The ID of the Shelly should match the ID of your Shelly. Here you can enter as many actors as you want, each separated by a ,
.
Now you have to link a “machine” to an “actor”.
Go to the line starting with {actors_connections =
and after the following [
you add
{ machine = "Identifier-of-your-Machine", actor = "shelly1-E8DB84A1CFF4" }
using your own Name-of-your-Machine and the Shelly-ID of the related actor.
Now you have to set the “access-permissions” to your “machine”.
Go to the line starting with , machines =
. and after the {
you can add a machine:
Identifier-of-your-Machine =
{ description = Some "I am your first Testmachine"
, disclose = "lab.test.read"
, manage = "lab.test.admin"
, name = "Name of the Machine"
, read = "lab.test.read"
, write = "lab.test.write"
},
Please be aware that “Identifier-of-your-Machine” is the internal ID for BFFH. The name of the machine shown in the App will be “Name of the Machine”.
The given permissions are ok to start with (if you did not change the roles of the Testuser). To find out more about the permission concept see the “configuration” part of the documentation.
- save (if you are using nano, this will be Ctrl-O )
-restart the BFFH-server
Important
every time you change the bffh.dhal you need to reload the settings (otherwise the App will not connect to the server on restart):
./diflouroborane -c examples/bffh.dhall --load examples/users.toml
and restart start Diflouroborane:
./diflouroborane -c examples/bffh.dhall
Open the App, an you should see the newly created machine in the list. By tapping “USE” you will activate the machine (Shelly will click, the MQTT-listener should promp an “on”), by tapping “GIVEBACK” you will deactivat the machine.
Creating a QR-Code for your machine
A QR code allows users to directly enter the UI of the machine, where the machine can be used or given back. The QR code should contain the following content:
urn:fabaccess:resource:{MachineID}
e.g.
urn:fabaccess:resource:Identifyer-of-your-Machine
QR-Codes can be generated on various pages in the internet (e.g. https://www.qrcode-generator.de), the “Type” of the QR code should be “Text”. The generated code can be directly scanned by the FabAccess App in the machine overview.
Adding a user Adding a user to the system consists of two steps
- creating the user
- provide permissions
Users are defined in the file users.toml. To add a user simply add
[Name-of-the-User]
roles = ["Name-of-a-role/internal", "Name-of-another-role/internal"]
priority = 0
passwd = "the-chosen-password"
noot = "whatever-this-means"
Adding users or changing existing users does NOT require to restart the system (tested?)
The permissions of the user are defined by the linked roles. The roles are defined in the file bffh.dhall.
Open the file bffh.dhall an find the line starting with , roles =
The concept of the role management is described in the “configuration” part of the documentation.
To keep it simple we create a role called “ChainsawUser”
ChainsawUser =
{ permissions =
[ "lab.machines.chainsaw.write"
- allows the user to use the machine
, "lab.machines.chainsaw.read"
- allows the user to read see the status of the machine
, "lab.machines.chainsaw.disclose"
- allows the user to see the machine in the machine overview
]
If a user assinged to this role uses the chainsaw, no other user is able to use it until this user gives the chainsaw back. To unlock the machine from the user, admin permissions are needed. So there could be an admin role like
ChainsawAdmin =
{ parents = ["ChainsawUser"]
- inherits all the permissions of the ChainsawUser
, permissions = ["lab.machines.chainsaw.admin"]
- addinional admin permissions
}
The machine
should be defined as:
Identifier-of-your-Chainsaw =
{ description = Some "Beware of Freddy!"
, disclose = "lab.machine.chainsaw.disclose"
, manage = "lab.machine.chainsaw.admin"
, name = "Chainsaw"
, read = "lab.machine.chainsaw.read"
, write = "lab.machine.chainsaw.write"
},
If a user is asigned to “ChainsawUser/internal” he/she will be able to see and used the chainsaw in FabAccess.
Using a Shelly as a door opener (electronic wise) In version 0.2 a door opener functionality is not implemented. The specific behaviour of a door opener is, to activate a door openeing relais only for a few seconds. This behaviour is not yet implemented in FabAccess, but there is decent way to implement it by other means. The simple Shellies (1, 1pm, 2.5) have an internal timer “AUTO-OFF” which can be set. To use this timer you have to access the settings of the Shelly via a browser on your computer. To do so, you have to know the IP adress your Shelly is assinged to. This can normally found out in the router of your Wifi. By entering this IP adress in your browser you will access the main menu of your Shelly.
Go to “Timer” and set the “AUTO-OFF” to e.g. 3 seconds.
Define a machine called “door” in the bffh.dhall
- define the actor:
shelly1-123456789ABC = { module = "Shelly", params = {=}}
- define the machine:
{ machine = "door", actor = "shelly1-123456789ABC" }
- set permissions for the machine:
door =
{ description = Some "close it firmly"
, disclose = "lab.door.disclose"
, manage = "lab.door.admin"
, name = "Door to the Lab"
, read = "lab.door.read"
, write = "lab.door.write"
},
- create a role having ALL permissions to the door
DoorUser =
{ permissions =
[ "lab.door.write"
- allows the user to use the door
, "lab.door.read"
- allows the user to read see the status of the door
, "lab.door.disclose"
- allows the user to see the machine in the machine overview
, "lab.door.admin"
]
- assign the role DoorUser/internal to all users
It is imporatant all users have admin aka manage permissions, as the request to open the door by a user, thet the door “in Use” by this user. The door can only be re-activated when the previous user “un-uses” the door or if an othe user can “force free” the door prior to using the door hin/herself.
Note in this special case, where all users will need admin capabilities the role could also contain only the permission lab.door.use
and all permissions (disclos, manage, read, write) assigned to the machine would simply match lab.door.use
(e.g. disclose = “lab.door.use”`).
**Identify if a machine is just switched on or realy running (TO-DO)
Audit Log¶
Bffh will log state changes into the audit log file, one per line.
Audit log entries are for now JSON:
{"timestamp":1641497361,"machine":"Testmachine","state":{"state":{"InUse":{"uid":"Testuser","subuid":null,"realm":null}}}}
NFC Cards (FabFire)¶
Functional Principle¶
Basic¶
Card authentication using NXP/MiFare DESFire cards. These cards have the ability to restrict access for data on the cards using symmetric encryption and using a keyed Diffie-Hellman to prevent eavesdropping by any relaying party. A card has several “applications”, containing up to 32 files. A file can be read or written. Both kinds of access can be restricted to parties knowing a PSK, on a file-to-file basis.
Files¶
The current system uses File 0001 through File 0003:
File 0001 allows public (i.e. unauthenticated) read access and contains the Strings
FABACCESS
, DESFIRE
, and 1.0
as packed list of UTF-8 encoded zero-terminated strings.
Examples:
FABACCESS\0DESFIRE\01.0\0
This file serves an identifier, allowing a server to verify if it is able to use this card.
File 0002 allows public read access and contains:
An URL-encoded name of the issuing lab as URN in the format
urn:fabaccess:lab:<labname>
Examples:
urn:fabaccess:lab:innovisionlab
urn:fabaccess:lab:Bibliothek%20Neustadt%20Makerspace
urn:fabaccess:lab:Offene%20Werkstatt%20M%C3%A4rz
A valid IRI pointing towards the bffh instance running for this lab. This bffh SHOULD be reachable from the internet. Using private use IP addresses or IRIs that resolve to such may be necessary for labs behind restrictive firewalls or due to local policy. The IRI MUST use the “fabaccess” scheme, and SHOULD NOT contain an userinfo, path, query, or fragment part. Examples:
fabaccess://innovisionlab.de/
fabaccess://192.168.178.65
fabaccess://fabaccess-server.localnet
A zero-terminated list of UTF-8 encoded IRIs giving contact options to notify the issuer or owner in case the card has been lost. Issuers SHOULD set one value on card creation and MAY allow card owners to change or add values of their choosing. Examples:
mailto:lostcard@innovisionlab.de
https://innovisionlab.de/lostcard
https://werkstatt-märz.decardlost.php?action=submitcardlost
File 0003 allows public access or access using a key, at the issuers option. It contains a token that can be used by the home server of the card owner to identify the card owner. The format of the token MUST NOT be relied on by any party except the home server.
FabFire Specification¶
Application Identifier (AID): 0x464142
NFC Implementation¶
C# - https://gitlab.com/fabinfra/fabaccess/nfc Rust - https://gitlab.com/fabinfra/fabaccess/nfc_rs
Tools¶
Tool for provisioning new cards for use with the FabAccess card system. https://gitlab.com/fabinfra/fabaccess/FabFire-Provisioning-Tool
FabFire adapter translates mqtt messages from the reader hardware to api https://gitlab.com/fabinfra/fabaccess/fabfire_adapter