Skip to content
boltgolt edited this page Apr 26, 2022 · 4 revisions

Introduction

By default Howdy will authenticate you the moment you have been successfully recognized. However, a lot of users want to have more control over the authentication flow. This is where rubber stamps can help. Rubber stamps are available in Howdy 3.0.0 and up.

Stamps are activated just after your face has been successfully recognized and can approve or deny the authentication. They have to be manually enabled or disabled in the config.

Stamp rules

Stamps are enabled or disabled by adding a stamp rule to the config. Stamp rules consist of several elements, separated by one or more whitespace characters:

  • Rules always start with a whitespace character, preferably a space. This signals to the .ini parser that the line is still part of the stamp_rules config variable.
  • Next is the name of the rubber stamp to run. This should be the same as the file containing the rubber stamp code. For our example this will be the "hotkey" rubber stamp.
  • The timeout length comes after that. This is the maximum amount of time (in seconds) the stamp is allowed to run. It is expressed as a float, optionally followed by a "s" to help recognize the number as a timeout. Currently the timeout can only be set in seconds.
  • Then comes the failure mode. This can either be "failsafe" or "faildeadly", if another string is given the rule will default to failsafe. Setting the failure mode to failsafe will cause the entire authentication to fail upon timeout, unless the user explicitly approves it. Faildeadly is the exact opposite, authentication is approved on timeout unless a user explicitly prevents it.
  • The last part is optional and contains special settings that are different for every stamp type. Check the documentation for the specific stamp you are using to see what settings are available. The format is the name of the setting followed by an equal sign and the value you want to set the setting to.

The simplest rule possible would be:

 hotkey 5s failsafe

This will wait for a keypress for 5 seconds. If no hotkey is pressed within that time then the authentication will be aborted (failsafe).

A more advanced rule could be:

 nod 10s faildeadly min_directions=4

This will wait for the user to nod yes (authenticate) or no (abort) for 10 seconds. Because the rule sets the min_directions setting to 4 the user needs to do at least 2 full nods. If not enough nods have been detected then the authentication will pass anyway (faildeadly).

Availible stamps

Howdy comes with a few stamps pre-installed. All the listed settings for these stamps refer to the extra settings, every stamp has a timeout and failsafe keyword in their rule.

Hotkey (hotkey)

The stamp will wait till the user presses a predefined key to either abort or authenticate. Accepts any key or key combination that the keyboard module accepts.

Setting name Value Description
abort_key esc When pressed, this key (combination) will abort authentication.
confirm_key enter Same as the abort key, but confirms authentication.

Nod (nod)

This stamp will track the relative movement of the tip of your nose. Nod up and down to confirm authentication, shake your head left and right to abort authentication.

Setting name Value Description
min_distance 6 The minimum relative distance your head has to move. It's best to play around with this value to see what works best.
min_directions 2 The minimum amount of alternate directions your head needs to move in. With the default value of 2 you have to preform two direction changes. For example: Moving your head left, then right, then left would be the minimum.

Writing new stamps

Howdy is open for anyone to create and publish their own stamps. Stamps that are useful to many people can be included in Howdy directly. Open a PR or issue if you want to include your stamp in Howdy by default.

The documentation below will walk you through writing your own stamps step by step.

Creating a new file

For this tutorial we will write a stamp called "roulette" that will have a random 20% chance of aborting authentication.

After every authentication Howdy will automatically scan for any enabled stamps in the rubberstamps folder. This means that you only have to create a file in that folder to make your code runnable by Howdy.

For our example we will create a new file called roulette.py in the rubber stamp folder located at /lib64/security/howdy/rubberstamps.

Extending the RubberStamp class

Adding our file to the rubber stamp folder will import our file, but we still need to add code for Howdy to run. We do this by extending the RubberStamp class Howdy provides. You can import this class by adding the following line to the top of your file:

from rubberstamps import RubberStamp

Then we need to extend this class with our own functions. Declare your own class and make sure that your class name is exactly the same as the name of your file. Since our file is called roulette.py, we call our class roulette:

class roulette(RubberStamp):

Inside this class we create a new function called declare_config(). This function defines the config settings that a user can change within the stamp rule in the config file (e.g. probability=1). Declare your settings by using the setting name as a key in the self.options dictionary and storing the default value of the setting as its value.

We want to be able to set the probability that our example roulette stamp aborts authentication. As said above, we do this by adding a key called probability to the dictionary self.options, with a value of 0.2 to reflect the 20% chance the user has by default:

def declare_config(self):
	"""Set the default values for the optional arguments"""
	self.options["probability"] = 0.2

Next up is the function that will actually be used to do most of the logic, which is simply called run(). This function should contain the logic to confirm or abort authentication. Do this by returning True to confirm, and False to abort.

Any setting you have declared in declare_config() can still be read the same dictionary. The default value has now been overwritten with the user defined setting from the config.

Make sure that you never import any libraries outside of the run() function. If you import libraries anywhere else in the file they will be imported even if the user does not enable your stamp.

For our example we simply generate a random number between 0 and 1 and see if it's lower than our probability setting:

def run(self):
	"""Abort the authentication randomly (the user asked for this)"""
	import random
	return random.random() > self.options["probability"]

That's all you need for a basic class! The complete roulette class would look as follows:

from rubberstamps import RubberStamp

class roulette(RubberStamp):
	def declare_config(self):
		"""Set the default values for the optional arguments"""
		self.options["probability"] = 0.2

	def run(self):
		"""Abort the authentication randomly (the user asked for this)"""
		import random
		return random.random() > self.options["probability"]

There are a few more advanced topics explained further down the page, notably the use of timeout and failsafe.

Adding your rule

Now that our class is done we can add the new stamp do the Howdy config file. First, open the config file (sudo howdy config) and navigate down to the [rubberstamps] section and make sure that they are enabled.

Finally, we can add our own rule here to enable the new stamp. Use the same name as you used as the class and file name. Add a timeout and failsafe keyword as they are required but not used by this stamp. You can also add the optional probability setting if you want to. The rule should look like this:

 roulette 1s failsafe probability=0.5

Don't forget that rules should always start with a space or other whitespace character.

After you save the config file your stamp should be active! To see more details about the execution of your stamp it could be useful to enable the verbose_stamps config option under the [debug] section at the bottom.

Advanced topics

Interacting with the GTK UI

Howdy shows an authentication UI if the howdy-gtk package is installed, and stamps can set their own text in this UI.

self.set_ui_text("Big text, not long")
self.set_ui_text("Subtext, longer and smaller", self.UI_SUBTEXT)

self.set_ui_text("This is big text too", self.UI_TEXT)

Set the subtext to an empty string to only show the big text.

Timeout and failsafe

The timeout and failsafe options in the stamp rules are parsed automatically. You can access them like any other (optional) options through the self.options dictionary.

# Float with the total amount of seconds a stamp should run for
self.options["timeout"]
# What to do on timeout: True if auth should be aborted, False if auth should be confirmed
self.options["failsafe"]

Self object

The class has access to a few helper variables.

# True if verbose stamp logging is on, check this variable before logging to console
self.verbose
# Complete Howdy config object
self.config
# The opencv instance
self.opencv 
# Video capture stream
self.video_capture
# Opencv face detector
self.face_detector
# Opencv pose predictor
self.pose_predictor
# CLAHE
self.clahe