personal account manager webapp
The meta data in the table is populated during the build process when the on-line help is generated.
Field | Value |
---|---|
Author | Joe Linoff |
Copyright (©) | 2022 |
License | MIT Open Source |
Version | 1.1.20 |
Bootstrap Version | 5.3.6 |
Build | 2025-06-16 19:03:39 -0700 |
GitCommitId | 4619ff9 |
GitBranch | main |
project | https://github.com/jlinoff/pam |
webapp | https://jlinoff.github.io/pam/www/ |
help | https://jlinoff.github.io/pam/www/help/ |
PAM or Personal Account Manager is a free and open source, single page web application that is designed to help you conveniently and securely manage your confidential information like passwords inside the secure context of your web browser as dynamically configurable records that can be searched without having to rely on services from a third party server because they are stored in a file that you control either on your local device or on a cloud based file server.
The PAM file is encrypted both in transit and when stored so the contents are safe from hackers if the file was stolen assuming, of course, that the password you used to encrypt it was strong.
The PAM file flow is shown in the figure below. Note that the save device and the load device could be the same device.
You can access PAM from your own secure web server (including localhost) or from the public github.io server. In either case, once the application is loaded into your browser or run as a local web app (PWA) there is no other communication with the web server which you can verify by monitoring outbound network traffic.
In addition, PAM is designed to be mobile friendly so you can access it from your laptop browser as well as your mobile phone and tablet.
It looks something like this on my iphone in dark mode for the fictitious example records that are provided by PAM to practice with, as described in the Load File section later on.
And something like this in light mode.
At the bottom left of the screen there is a button that allows you to
toggle between light and dark mode. It looks like a sun (switch to
light) in dark mode:
and like a moon (switch to dark) in light mode:
.
Dark and light mode examples will be intermixed throughout this document.
The records appear as accordion entries that expand when you click on them as shown below.
Once the record is expanded you simply click on the clipboard
icon associated with the record field you are interested in (like the
password) to copy its value to the system clipboard so that it can then
be pasted them into the appropriate login field. You can click on the
eye
icon to see the password in plaintext. By default all record fields
containing sensitive information,like passwords, are masked so that a
casual observer cannot see it.
You can even include images as shown in this example which is also provided by PAM to practice with and, like the examples above, is also described in the Load File section later on.
There are other features like memorable password generation and customized record fields that are described in the documentation below.
Please note that this is not the first tool I have written to manage passwords but it is meant to be the last. If you are interested in what motivated me to create yet another tool, see the Security Considerations and Reasons to consider using PAM. If you are interested in the genesis of PAM and the stories of its predecessors, see the History section.
I hope that you also find useful in some way.
PAM is a pretty simple application. It is basically a record editor that runs in your browser that allows you to create records with interesting information that can then be stored and retrieved in a secure way.
This section talks about why you may not need or want to use PAM.
It is very reasonable to ask yourself why, if PAM is like an editor, you can’t simply just use something like an Excel spreadsheet or a text file editor or keep passwords on a sheet of paper or use one of the many commercially available password managers?
That is an excellent question. The answer is that you can and, if you are already using an Excel spreadsheet or a text file editor or a sheet of paper or a password management service or any other method that works for you, you should.
Even if you do not already have a method for managing passwords PAM may not be the right choice. PAM requires that you understand a bit about HTML input and textarea elements which may be confusing. Also the PAM user interface (UI) and record data model may be confusing or hard to understand and use because I am not a UI programmer.
The bottom line is that I wrote PAM to provide some features I wanted and to address some concerns I had with existing approaches. Those features and concerns are discussed in the next section to help you understand my reasoning so that you can decide whether any of them are important to you. If you don’t care about the features and the concerns that bother me, there is no reason to use this tool.
This section presents the nine primary reasons that motivated me to develop PAM. They are provided to to help you determine whether PAM might be interesting to you.
PAM is a single page web application (SPA) that has no backend which means that it never communicates with an external site which protects it from some types of cyber attacks as detailed in the Security Considerations section.
In PAM, information is organized into files composed of records that each have a unique title and are, in turn, composed of fields that have a name, a type and a value. This approach is similar to organizing information using index cards or a rolodex.
Following the index card analogy a little further, we can use a simple example to understand the record model a bit better.
A recipe would be something you might store on an index card. Each recipe could be a single record that might contain the title (the name of the recipe), the ingredients (a field) and the instructions (another field).
So what would a simple dessert recipe look like as a in PAM record? Well, if you had a simple dessert recipe like this written on a card with an attached picture.
Ice Cream Sundae ingredients 1. 3 scoops vanilla ice cream 2. 1 banana (sliced up) 3. chocolate sauce 4. (optional) nuts 5. (optional) Maraschino cherry 6. whipped cream instructions 1. put ice cream in bowl 2. add slices of banana 3. add nutes 4. pour chocolate on top 5. add whip cream 6. put the cherry on top.
It would look like this when you create it in PAM.
It would look like this when you view it in PAM in edit mode.
In this recipe
record, the title is
"Ice Cream Sundae"
and the two fields ingredients
and instructions
contain the multiline (textarea
)
descriptions of what the ingredients and instructions are for this
specific recipe. And, finally, there is an html
field that
contains the image.
Note that the record field names ingredients
and
instructions
used in this example are custom field
names. They are not available by default. The html
field
is a default field.
Custom fields can be created by adding new fields to the default fields defined in the preferences so they are available all of the time.
For this example I created two new textarea fields named
ingredients
and instructions
so that users could enter
multiple lines and removed all of the other default fields except the
html
field because they were not needed. I kept the default
html
field because I wanted to be able add pictures to the
recipes. Here is what the preferences look like after the modifications
were made.
Of course, there are many other types of records that might be interesting to store in PAM that can use the default record fields as is. See the Fields section for a description of the default records and their types.
One common one is a record for each account that you need to login into where you information about how to login is stored so you don’t have to remember it.
Such an account
record would have, at a minimum, the
web address (URL), the login name and the password of the account.
Note that this simplified example is only meant to show the basic idea of importance of supporting record formats that are different than recipes. For a real account record you would probably want to add additional fields like an email address or a notes field.
Here is what the simple account record would look like.
Note that the password is hidden in the example above. PAM always hides the contents of passwords by default.
Both records look quite different. Recipes records have fields for
ingredients
and instructions
whereas account records have
fields for the url
, login
and password
. However, in
both cases they have the same basic structure: a title and a set of
fields that are relevant to recipes or accounts.
You could easily imagine defining other records that contain
information for other topics like books read
or
unidentified aerial phenomena
or bird
watching
which would undoubtedly require different fields. The
idea of topics is dicussed in more detail in the Topics section.
In my view, this approach of using records composed of fields does a better job of representing this type of information than a spreadsheet or a text file.
PAM allows you to search records by their title or their field names and values. It also filters out the records that don’t match to make it easier to see the matching records visually.
The availability of fast interactive searching makes finding records easy.
This is what search/filtering looks like for all example records that
contain a g
in them. Note that, by default, search operations are
case insensitive but that can be changed in the preferences.
Note that regular expressions can be used as well as shown in the
example below that looks for records that start with g
.
See Search for more details.
I always find it hard to come up with passwords in the spur of the moment so PAM was built with the ability to automatically generate passwords.
Of course almost all browsers and password tools provide this same capability nowadays, but they tend to generate secure, cryptic, hard to memorize passwords which is perfectly fine for passwords for most accounts.
But there are a cases when you need a password that must be typed in manually like the login password for a computer that does not use biometric scanning or a key FOB. In those cases it is beneficial to have a password that is secure, easy to remember and easy to type because you cannot access a password management system before you login.
I call passwords of this type memorable passwords. They are composed of common lower case English words with an optional prefix, an optional separator between each word and an optional suffix.
Often, the prefix and suffix are used to guarantee that the password contains the correct mix of characters that the authentication system requires, like, at least one capital letter, at least one digit and at least one special character.
To make these concepts a bit clearer, here are examples of a cryptic and a memorable password.
cryptic | Rf5NaR7LH2LbZMRhkPCfeG8 |
memorable | A1/health/mpegs/hopes!! |
In this example, the memorable password word separator is
"/"
, the prefix is "A1/"
(capital letter and
digit) and the suffix is "!!"
(special characters).
To help with this, PAM was built with the ability to generate cryptic and memorable passwords.
For more detailed information about password generation in PAM see the Password Fields section.
PAM uses files to load and store the record data.
Using a file means that the user does not have to rely on the cybersecurity infrastructure of a company running a web server and storing your data at their site or another third party site. This was alluded in Reason 1: No Client Server Communications but that is not the only advantage of using files.
A PAM file is composed of a set of records. Any records you
like. You can use a single file for all of your records or you can have
multiple files where each file contains records that are somehow related
like records of recipes
or book reviews
or my favorite species of Euglena
.
What this means is that you can group records associated by a topic in different files to make them easier to organize and find. This ability to organize files around topics is the other reason that I prefer the file based storage model.
For a more detailed discussion about how the user controls the organization of the records and fields in a file see the Reason 2: Record Model section of this document.
As a side note, I store my personal PAM record files in Apple iCloud which is one of many cloud based storage services like Dropbox, Google Drive and Microsoft OneDrive.
For files I want to share with other folks, I use Google Drive to store the file and then share it.
When properly configured all of these storage services store the PAM record file in the cloud so that it is available to anyone who knows the file password as long as their laptop, phone or tablet is authorized to access the storage service.
Of course you could simply load and save the data to a local file but that might restrict your ability to access to it from other devices (like mobile phones or tables). Not only that but you would have to be very diligent about keeping it backed up so that you would not lose data if the local file was corrupted or lost.
When records are stored in a PAM file they can be encrypted
using a password. The password is then used by an NIST
certified, symmetric encryption algorithm:
AES-256-CBC
to encode the records.
Using a certified encryption algorithm provides a strong security guarantee which means, that if an encrypted PAM file is stolen, the record data is considered safe from hackers trying to crack the contents if a strong password was used.
Passwords like secret
or password123
or any other password that can be found in freely available password
dictionaries like the Kali
password dictionary are not strong and will not
protect your data because they are easy to guess.
Always use a strong password to make it hard to guess. Typically a strong password would have at least 20 characters would not include any personally identifiable information (PII) like your name, birth date or address. Also never, ever use the same password for two different sites. This is to protect you from hackers if a site you use to is attacked and your password is stolen.
I recommend reading NIST Password Guidelines for more information about how to create strong passwords.
As an interesting aside, note that AES-256-CBC
algorithm
is considered to be reasonably resistant to quantum attacks as discussed
in the literature. For example, here
is one relevant exchange from a crypto.stackexchange.com
discussion.
PAM encryption and decryption operations are provided by and run inside the secure context of the browser. This is the same secure context used for accessing sites securely for transactions, like your bank. In practice this means that you must access PAM from an HTTPS site.
The safety and security of secure context operations is taken very seriously by the internet standards organization and the organizations that develop the major browsers.
You can read more about secure contexts here.
Passwords and other secrets are automatically hidden on the screen (displayed as asterisks) so that someone looking over your shoulder cannot read them unless you choose to make them visible. You can read more about why this is beneficial in the Security Considerations section.
This is the default hidden view of a password. You can see that the password value is all asterisks.
This is the same view of a password when it is not hidden. You can now see the password value.
The record files can be accessed from mobile devices so the user has access to the records anywhere as described in the Reason 5: File Based Storage but that does not necessarily imply that the interface is mobile friendly.
What makes PAM mobile friendly is that it is implemented using the bootstrap-5 library to make the interface work better in the browsers present on mobile devices.
Last but not least, one compelling reason to try PAM is that it is free and open source software (FOSS) so you can try it without any obligation or cost. You can also help find and fix bugs or improve the UI.
Records composed of fields are a key concept in PAM as described in Reason 2: Record Model.
This section talks about how records are presented in PAM
using an example with seven records that contain confidential
information for Amazon
, Email
, Facebook
,
Github
, Google
, Netflix
and Stack Exchange
fictional accounts from the Load File
example.
See the Create New Record section for details about how to create records and the Topics and Fields sections for more details about their contents.
We start with the unexpanded view of all records as shown below.
PAM presents the records as an accordion. Each record is one entry in the accordion that you can expand to view the record fields or delete, clone or edit edit the record.
To get the information for an account you click or tap the button.
At the top of the screen is the search bar and, at the far right, the menu.
At the bottom of the screen is a status bar that shows status messages.
Once you click on or tap a record it expands as shown below where the
Facebook
record was tapped.
You can see that there are three fields in the record: url
,
login
and password
, next to each field there is a icon
that looks like a clipboard
.
If you click or tap the clipboard icon, the field contents will be copied to the clipboard so that you can paste them into a login dialogue.
In addition to the clipboard icon there is another icon that looks
like an eye
that shows up for password field. If you click or tap it, the password
will be shown in plaintext and the icon will change to an eye with a
slash through it
.
By default all passwords are hidden so that they are not visible to
casual observers. Click or tap it again to re-hide the password.
Passwords are correctly copied to the clipboard at all times even when
the password is hidden.
In addition there are three buttons at the bottom
to delete the record,
Delete
to clone the record and
Clone
to edit the record fields. Edit
As shown below.
The fields in records are completely customizable when you
select the "Edit"
option.
Fields are added to the record by selecting a new field from
the "New Record"
drop down menu as shown below for the
"Facebook"
record but these fields can also be
changed. See the Custom Fields and Field Types sections for details.
Fields are modified in the record by editing them directly
and they are deleted from the record by clicking on the
icon.
Topics define how records are related. They provide a convenient
abstraction for organizing related records in files. Topics are
completely arbitrary. For example a topic could be something like
recipes
or accounts
or
unidentified aerial phenomena
or my favorite
cryptography algorithms
or green things
.
One way to use topics is to keep records related by a topic in
separate files. For example, you could define a
file for all of your recipe records
(topic: recipes.txt
recipes
or stuff to cook
) and an
for your account records (topic:
accounts.txt
accounts
).
Or, you could completely disregard organizing by topics and put all
of your records into a single file like
.myrecords.txt
Note the use of the
extension in the
previous paragraphs. Although the .txt
file
extension is supported for record files and it works on laptops. It does
not always work on mobile devices so a records file named
.pam
might not be readable by the mobile
browser. Thus, I recommend using the myrecords.pam
for all
record files for maximum portability..txt
Records are composed of fields. Each field has a unique name, a type and a value.
The field name is arbitrary and is meant to describes how
the data in the field is used. For example, an ingredients
field
would indicate that the value is a list of ingredients and a
number
field would indicate that the value is a number. An
example of a field name might be mobile phone
.
The field type explicitly describes the type of data that
field holds like a number
or a phone
or an email
.
Types are built in and strictly enforced by javascript.
An example of the difference between a name and a
type would be a field named mobile
of type
phone. The name describes how it is used whereas the
type describes what the input type is which, in turn, dictates
what user inputs are acceptable. A description of each built in record
field type can be found in the Field Types
section.
The field value is the unique value for the field in an
individual record that is set when a field is created or edited. For
example, an field named email
of type email
could have a
value wombat@foo.io
the name and the type could
be the same for all records that had an email
field but the
value would vary.
The default record fields are the fields that are available in the
"New Field"
pull down menu when a record is created or
edited. They are defined in the Preferences
section and they are stored in each records file along with the
records so each records file can have different default fields.
For example a file of recipe records would probably want fields of
type textarea
named ingredients
and
instructions
but a file of books read
records
probably would not. Instead it might want text
fields
named author
and publisher
along with, possibly, a field
of type number
named copyright
.
See the Record Fields section for details about how to add or modify the default record fields in the preferences dialogue.
There is a second more obscure way to define field names. You can change field names when you create or edit an individual record by setting the Enable Editable Field Name preference.
This capability is not enabled by default to avoid confusion
between the name
input and the value
input as shown below.
Normally only the value
input is shown.
Typically there is no reason to change record field names on a per record basis. It is better to add the new record fields to the default list in the preferences.
Record field types define the type of each field that you define for
a record. They are based on HTML input element types except for
the textarea
type which is a HTML textarea
element that is displayed as preformatted text
(<pre></pre>) and the html
type which is
also a HTML textarea type but is displayed as raw HTML so it
can be used for inserting images. They are presented below as simple
types regardless of the underlying HTML element to avoid unnecessary
complexity.
You can change, add or delete record field names here if you
wish to customize the user experience but you cannot change the built in
types. For example, you change the record field name
note
from a textarea
field to a
text
but there is no way to add a new built in type to
the drop down list from the user interface.
These are the default field definitions.
The table below presents a brief overview of the default record fields and their associated built in types and when to use them. You can search the web for more details about HTML input types.
Type | Usage |
---|---|
datetime-local | A datetime text string. Use it if you only want to accept a datetime value. A typical usage might be the date that you finished reading a book. |
An email text string. Use it if you only want to accept an email value. A typical usage might be the email address of a contact. | |
html | Textarea data that is rendered directly as HTML. A typical usage might be to reference an image or to display formatted text. |
number | A numeric text string. Use it if you only want to accept an number value. A typical usage might be a measurement like height or width or any other numeric value. |
password | A secret text string that is normally displayed as asterisks
(**** ) with an eye
( |
phone | A phone number text string. Use it if you only want to accept a phone number value. A typical usage might be a mobile phone number. |
text | A string, like a name or keyword. You can use this for any text but
it is especially useful when a field can be multiple types like an email
or a name. A typical usage might be a login name where the value might
be a name like wileyor an email like wcoyote@acme.ioor a number like 12345678. |
textarea | A multi-line text box. A typical usage might be a note or a list of recipe ingredients. |
url | A text string that is a uniform resource locator (URL). Use it if
you only want to accept a URL value. A typical usage might be
the path to an account like https://google.com |
username | A username. This may be slightly different than a login because a
login could be an email address but, in general, it probably makes more
sense to user login rather than username . |
Remember that the types were not made up by me, they were taken directly from input element description here, the separate textarea element is described here.
It is oftentimes the case that all of the default record fields are not needed for the records you are managing or you may want to define new, custom fields that are more intuitive for your records. This section shows you how to do that.
Here is an example that shows a recipe record with ingredients
and instructions
fields.
Here is what the preferences look like after ingredients
and
instructions
record fields have been added and the previous
default record fields other than html
have been pruned
out.
Here is an example that shows an account record with url
,
login
and password
record fields.
Here is what the preferences look like with the other fields pruned
out. The url
, login
and password
record fields are
part of the default.
This is what they will look like in the "New Record"
pull down menu when creating or editing a record.
Password fields are a special case for the following three reasons.
First, they provide a generator that allows you to automatically create passwords at the click or tap of a button. For information about preferences that can be used to customize password generation see Password Preferences
Second, they always hide the value by default so that it can be seen by someone observing your screen.
And, finally, because they provide the ability to generate two different types of passwords: cryptic and memorable.
Cryptic passwords consist of letters, digits and special characters.
Here is an example: 'N5yAb!XfGa3vELPsK95K4/AAz8mts'
.
Cryptic passwords tend to be hard to memorize for most people.
They are perfect for cases where you don’t have to type the password in because they are hard to crack.
Memorable passwords are used to define passwords that must be typed in manually, as described in the Reason 4: Automatic Password Generation section which means that it is important that they are secure, easy to type and to remember.
They are composed of common lower case English words with an optional prefix, an optional separator between each word and an optional suffix. Often, the prefix and suffix are used to guarantee that the password contains the correct mix of characters that the authentication system requires, like, at least one capital letter, at least one digit and at least one special character.
The security rationale for memorable passwords is described in this article: The logic behind three random words.
Here is an example: 'Z0/rebates/restructuring/jamaica??'
where the prefix is 'Z0/'
, the separator is
'/'
and the suffix is '??'
.
Memorable passwords tend to be easier to memorize than cryptic passwords for most people.
Here is an example that shows a password in its standard hidden form.
To make the password visible, click or tap on the
icon.
The password can be copied to the clipboard when it is hidden by
clicking on the
icon.
Here is an example that shows a password in its visible hidden form.
The password can be copied to the clipboard by clicking on the
icon.
To hide the password, click or tap on the
icon.
This is what the password field dialogue looks like with no generator.
When you click or tap on the
icon,
cryptic and memorable passwords are generated and the password generator
dialogue appears.
It always generates five memorable passwords to provide choices. I found that more useful than the original implementation which only had a single choice.
The decision to present five memorable passwords was completely arbitrary but it seems to work well enough for my needs and can easily be changed.
This is what the password generator looks like with annotations.
If you click or tap on the
icon a
second time, new passwords will be generated.
You must click or tap on the
icon to
close the dialogue.
I chose this approach because I wanted the
icon to be
used to generate new passwords.
In retrospect, that choice may not have been the most intuitive way to implement closing the generator dialogue it but it works well enough and can easily be changed if it turns out to be too cumbersome.
To choose a generated password simply click or tap on it and it will be added to the field value.
See the Password Preferences section about how to define the prefix and suffixes for memorable passwords.
PAM is a simple single page web application (SPA). It consists of three basic parts: the menu and search section, the records section and the status section.
It looks something like this
The top section that contains a search input and a menu.
PAM allows you to search records by their title or their field names and values to filter out records that do not match the search pattern. This is extremely useful when the number of records grows.
The search function at the top left supports case insensitive searches and regular expressions to make it easier to find records.
This can be very helpful for finding out where old passwords and obsolete accounts are still being used.
Here is the made up list of account records from the Load Files example:
Here is the same list after filtering for those whose titles contain
the letter "g"
. Note that searches are case insensitive but
you can change that by unsetting the Case Insensitive Searches
preference.
To filter only those that start with "g"
you would use
this regular expression search term instead: "^g"
. which
would result in only two records found.
For more information about regular expression syntax see the documentation for Javascript Regular Expressions.
For more information about how you control the all of the available search options see the Search Preferences section.
The menu at the top right is the control center for the application it has a number of options as you can see below. This is what it looks like.
As you can see, there are seven menu options:
Click or tap on the
entry to see information about the app. See the About section for more details. About
Click or tap on the
entry to see the preferences dialogue which allows you to customize some
of the app behavior. There is a lot of stuff so you might want to read
the Preferences section before trying it. Preferences
Click or tap on the
entry to create a new record. See the Create New Record section for more
details. New
Record
Click or tap on the
entry to delete all of the records. This is useful for times
when you want to create a new collection of records that is saved in a
separate file. For example, if you wanted to create a collection
personal accounts in one file and a collection shared accounts for a
group of folks (like a development team sharing AWS accounts). Clear
Records
Click or tap on the
entry to load a records file. See the Load
File section for more details. Load
File
Click or tap on the
entry to save all of the records to a file. See the Save File section for more details. Save
File
Click or tap on the
entry to see this help message. Help
Underneath the top level bar, in the middle, is the records section. Each record is shown as an entry that is displayed by its title. If you click or tap on the record title, the record will expand to show the record contents (fields) and provide options for deleting, cloning or editing the record contents.
This way of presenting the records is called an accordion display.
Below you can see how it expands after the Facebook
entry has
been selected.
The expanded Facebook
record has three fields: url
,
login
and password
.
You can copy the field values to the clipboard so that they can be pasted into login forms.
Note that the copy works for passwords whether the password is visible or not.
You can also click or tap on the title of the opened record to close it.
Each of the record management options is discussed in more detail in the Functions section.
Below the records section, at the bottom, is the status section where ephemeral status messages are displayed. The messages disappear after about 1.5 seconds but the duration is controlled by a preference that you can set. See the Preferences section for more information.
The status messages are used to provide activity feedback like showing how many bytes were copied to a clipboard when a copy button is clicked or tapped as shown in the example below.
The following sections will go over the basic menu functions that PAM provides.
In a nutshell they are:
Each function will be discussed in a separate subsection below.
Note that Preferences were not included because they have their own top level section in this document.
click or tap on the About
menu entry to get information about
PAM. You can even add custom HTML through the preferences that
is stored for each PAM file.
Here is a screen shot of what you would normally see with no customization. Of course details will vary, like the Commit, Branch or Version fields.
Here is the About
dialogue with a simple custom message that
uses bootstrap formatting classes.
Custom messages are defined in the Custom About
field in the
Preferences as shown below. You can used
plain HTML or bootstrap 5 classes (as shown in this example).
The motivation for allowing custom messages is that someone might want to share a PAM file or describe how the records are related. The custom message would allow the person to provide their imprimatur on the collection.
Before reading this section, please make sure that you are familiar with the ideas covered in the Topics, Fields and Password Fields sections.
Creating a new record is a very common activity in PAM so I tried to make it as easy as possible.
There are three different methods you can use to create new records:
New Recordmenu option,
Each method is discussed in detail in the following subsections.
The first method, creating the record by clicking or tapping the
New Record
menu option in the application, is probably the best
way to create the first new record for a topic family. This is also
known as the menu
approach and is shown below.
To show how it works, we will create a recipe record using
ingredients
and instruction
fields. But first we need to
define them as default textarea
fields in the Preferences dialogue. So the available records
look like this.
To create a new record using the menu approach click or tap on the
"New Record"
option from the menu.
That will popup a dialogue that looks like this.
You can now type in the record title.
From there you click or tap on the "New Field"
pulldown
to select and create the first record field. Don’t worry if you select
the wrong one, they are easy to delete.
Here is where you select ingredients
for the first field.
Populate it by typing into the textarea
box.
Now do the same thing to create an instructions
field.
One interesting thing to understand is that you can change the order of the fields by dragging them up or down. To do that select the field title at the top of the box (fieldset) and move it. This can also be done when editing the record.
Here is what it looks like when I dragged the instructions
field up.
I then dragged instructions
field back down because it should
appear after ingredients
field.
When you are finished click or tap on the "Save"
button
to save it and you will see it show up as a new record in the records
part of the screen.
You can click or tap on the record to expand it and see the fields you just defined.
The second method, creating a record by cloning an existing record, is useful when you want to use the same fields as the existing record. It is a great way to guarantee uniformity. Although if the number of fields is small using the first method is also fine. Here is what the clone option looks like.
Cloning a record is simple. Just expand a record and click or tap on the clone button and an edit dialogue pops up.
Using the record that was created in the previous section here is
what happens when you click or tap the "Clone"
button.
The clone operation created a new record with a slightly modified
title Ice Cream Sundae Clone
because the record title must be
unique and the same fields as the original record.
At this point you would typically change the title and field values but for this demonstration will not do anything. PAM makes sure that the title is unique so it can be saved.
Click or tap the "Save"
button and you will see
this.
PAM still remembers that you had the original record open. Just below it you will see the new cloned record.
The reason that the original record is left open is so that it is
easy to continue clicking or tapping the "Clone"
button to
create more records.
In this case we only care about one record so you can click or tap on the new record to expand it.
The third method, creating a record by editing a JSON record file, is
most useful if you are interested in creating records programmatically
(perhaps a subset of accounts that shared with a small group of users
that is automatically generated from a database). The example records
and recipes example files that are available in the Load
dialogue
are a great place to start.
This approach does not have any screenshots because it deals with PAM internals and may change from time to time. Instead a set of instructions is provided that should allows you to figure it out pretty easily.
Loaddialogue.
recordssection of the file and use that as a template to create more records.
The reason that this has to be done without a password is because I
have not yet written a command line utility to encrypt/decrypt the
files. It should be straightforward to do because it uses the standard
"AWS_256-CBC"
algorithm.
Beware! That the format of this record may change. This is just an example that shows how simple the format is.
{"meta": {
"date-saved": "2022-05-01T20:50:29.125Z",
"format-version": "1.0.0"
,
}"prefs": {
"passwordRangeLengthDefault": 20,
"passwordRangeMinLength": 12,
"passwordRangeMaxLength": 32,
"memorablePasswordWordSeparator": "/",
"memorablePasswordMinWordLength": 2,
"memorablePasswordMinWords": 3,
"memorablePasswordMaxWords": 5,
"memorablePasswordMaxTries": 10000,
"clearBeforeLoad": true,
"loadDupStrategy": "ignore"
,
}"records": [
{"title": "Amazon",
"fields": [
{"name": "url",
"type": "url",
"value": "https://www.amazon.com"
,
}
{"name": "username",
"type": "text",
"value": "pbrain22@protonmail.com"
,
}
{"name": "password",
"type": "password",
"value": "hr5Hn9pqm3u.VqMiALfdN-\""
,
}
{"name": "note",
"type": "textarea",
"value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nCras sodales elit in metus tempus, ut semper magna finibus.\nDonec aliquam elementum velit quis pharetra.\nPellentesque accumsan neque ut massa elementum mollis.\nNulla eget pellentesque est."
}
],
}
{"title": "Email pbrain22@protonmail.com",
"fields": [
{"name": "url",
"type": "url",
"value": "https://mail.protonmail.com/inbox"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22"
,
}
{"name": "password",
"type": "password",
"value": "rHfZ6bihw$g8ra$P4hHD"
}
],
}
{"title": "Facebook",
"fields": [
{"name": "url",
"type": "url",
"value": "https://facebook.com"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22@gmail.com"
,
}
{"name": "password",
"type": "password",
"value": "dOa#DirgJge67okTKtEzp.LSl"
}
],
}
{"title": "GitHub",
"fields": [
{"name": "url",
"type": "url",
"value": "https://github.com"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22"
,
}
{"name": "password",
"type": "password",
"value": "Aq7GdcOmYWVkyHEWEk6fBeJzm"
}
],
}
{"title": "Google",
"fields": [
{"name": "url",
"type": "url",
"value": "https://google.com"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22@gmail.com"
,
}
{"name": "password",
"type": "password",
"value": "NIJMeb8OfXEfshOG$db!"
,
}
{"name": "note",
"type": "textarea",
"value": "This is my primary email address.\nsecurity question:\n> what is a photon? gauge-boson"
}
],
}
{"title": "Netflix",
"fields": [
{"name": "url",
"type": "url",
"value": "http://netflix.com"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22@gmail.com"
,
}
{"name": "password",
"type": "password",
"value": "cGwJ$NPQ4SsI#haEsFRD"
}
],
}
{"title": "StackExchange (StackOverflow)",
"fields": [
{"name": "url",
"type": "url",
"value": "https://stackoverflow.com"
,
}
{"name": "login",
"type": "text",
"value": "pbrain22@gmail.com"
,
}
{"name": "password",
"type": "password",
"value": "FpnzQcuq0nk/PxlMdYJ_itnK"
}
]
}
] }
To edit a record, select it from the records list and click or tap on
the "Edit"
button to popup the edit dialogue which is
exactly the same as the dialogue used to create a new record.
In fact, it is implemented using the same code so you can use the instructions from the Create New Record section to understand how to change or add new fields.
To delete a record, select it from the records list and click or tap
on the "Delete"
button.
Beware!!! PAM trusts you!!
PAM will not ask you if you really want to delete the record. It will just go ahead and delete it without fanfare so be careful.
To clone a record, select it from the records list and click or tap
on the "Clone"
button. This will create a new record that
you can edit.
The clone operation is described in detail in the Create New Record section under the Method 2: Clone Approach subsection.
Clear all of the records currently defined.
This is normally done automatically when a new file is loaded but could be useful if you want to enter new a set of records from scratch using the currently defined fields. Of course, you could simply delete all of the records manually but this is simpler.
To clear all records choose the
option from the menu. See the Menu
section for screenshots. Clear
Records
This option will ask you to confirm.
To save records and preferences to a file by choose the
option from the menu. See the Menu section
for screenshots. Save
File
This is the save file dialogue.
If you want the records to be encrypted, enter or generate a password as described in Password Generator section.
If you want to copy the records to the clipboard enter a dot
"."
as the filename.
Make sure that you do not forget this password. It is the master password this is used to unlock all of the records and PAM does not keep track of it. That means that if the password is lost, PAM cannot recover the data it is lost forever.
More details about the encryption algorithm used can be found in Reason 6: Secure Context Encryption.
Note that if you do not enter a password, the output will be plain javascript that can be read by anyone.
Plain javascript is NOT secure.
If you have records with passwords ALWAYS use a password unless you understand the consequences. For example, saving the data without a password can sometimes be convenient because it allows you to see how the PAM data is organized which can aid automation.
To load records and preferences from a file by choose the
option from the menu. See the Menu section
for screenshots. Load
File
This is the load file dialogue.
If the file was saved with a password, you must enter that password or the file will prompt for the password when loading.
If you wish to load the example records file, click or tap on the
Load Example Records
button (#1) to load the following example
records that can be used to get you started.
If you wish to load the example recipes file, click or tap on the
Load Example Recipes
button (#2) and PAM will load this.
Click or tap on the Load Records from URL
button (#3) to load
a file from the web.
This is typically used when a PAM records file is shared because no changes can be made.
Click or tap on the Paste Records from Clipboard
button (#4)
to paste records from the clipboard.
This is typically used when records are copies to the clipboard from a save operation or manually after editing.
To get this help message, choose the "Help"
option from
the menu.
If you find a bug or want to request a change or submit an improvement, go to the Metadata section at the top of this help and click or tap on the project link.
Preferences allow you to customized the behavior of the app. The defaults are set so that most people will never have to change anything.
The preferences dialogue is a big one. It is broken into 4 sections to make it easier to understand:
Each preference is discussed in more detail in the subsections below.
These preferences control search options. See the Search section for an example.
If enabled, all searches are case insensitive, otherwise they are case sensitive.
The default is enabled.
If enabled, all searches look at the record titles, otherwise they do not.
The default is enabled.
If enabled, all searches look at the record field names, otherwise they do not.
The default is not enabled.
You would want to enable this you wanted to see records that contained a specific field.
If enabled, all searches look at the record field values, otherwise they do not.
The default is not enabled.
You would want to enable this you wanted to see records that contained a specific field value like an obsolete email or really old password.
These preferences control automatic password creation.
For more information about passwords see Password Fields
Defines the minimum length of generated cryptic and memorable passwords.
The default is 12.
I would recommend not making it shorter than the default unless a website specifically demands it because shorter passwords are easier to crack.
Defines the minimum length of generated cryptic and memorable passwords.
The default is 32.
I would recommend making it longer than the default if you can but many websites have an upper bound for the length of password. The chosen default seems to work for most of them.
Defines the minimum size of a word in a generated memorable password. > It has no affect on cryptic passwords.
The default is 2.
If you do not want short words like 'as'
or
'it'
, then make this longer. I would not recommend making
it shorter.
The string used to separate the words in a generated memorable password.
It has no affect on cryptic passwords.
The default is a single character: '/'
.
If you want to change the character, add any string that you like. It
can be multiple characters. Other reasonable choices might be
':'
or '.'
or '@@'
or whatever
you like. It is best not to use letters.
The minimum number of words in a generated memorable password.
It has no affect on cryptic passwords.
The default is 3.
The maximum number of attempts to generate a memorable password that meets the specified criteria from the other password preferences.
It has no affect on cryptic passwords.
The default is 10000.
There is normally no need to ever change this but, if you change it and make it too small, PAM will report errors if it fails to generate passwords after the maximum number of tries.
The prefix to add to all generated memorable passwords.
The default is ''
(empty string).
You might want to add a prefix or suffix to make sure that the generated passwords meet the requirements of websites that require upper case letter, digits and special characters.
For example, you might specify something like 'A1!!/'
to
meet the criteria which might create passwords like
'A1!!/html/wishes/combined'
or
'A1!!/rebates/restructuring/jamaica'
.
The suffix to add to all generated memorable passwords.
The default is ''
(empty string).
You might want to add a prefix or suffix to make sure that the generated passwords meet the requirements of websites that require upper case letter, digits and special characters.
For example, you might specify something like '/A1!!'
to
meet the criteria which might create passwords like
'html/wishes/combined/A1!!'
or
'rebates/restructuring/jamaica/A1!!'
.
These are the preferences that didn’t fall into the other categories.
Log status messages to the console as well as the screen to aid debugging.
The default is false which says do not log status messages to the console.
You might want to enable console logging if you are debugging a problem and are working in a browser that supports debugging.
Clear all records before loading records from a file.
The default is true which says to clear the records before a loading new records from a file.
If you set this to false, another option titled Load Duplicate
Record Strategy
will appear that is not normally visible to ask you
with strategy you want to used for conflicts.
You might set this preference to false if you want to to merge sets of records from different files.
Click this to add the Print option to the menu.
This is what the enable printing preference looks like in the preferences dialogue.
Once it is enabled, the Print
option will appear at the bottom
of the menu as shown below.
When you click on Print
, PAM will print the records with the
passwords visible. This is what it looks like for the example
records.
This capability is useful if you want a paper copy of your records but it is a security risk. If you choose to enable this option, make sure that the paper copy is stored securely.
Disable this option (the default) if you intend to share PAM records with multiple users from a read-only URL.
This preference is not visible unless the Clear Records On
Load
preference is false.
It presents three strategies for handling duplicate records during a
load operation: allow
, ignore
, replace
.
The allow
strategy allows duplicate records to exist by
cloning them. For example if a record with the title Google
exists in the records and in the file being loaded, the record from the
file would be renamed to Google Clone
.
The ignore
strategy ignores the duplicate record that is being
loaded. If there is a conflict it prefers the one already present.
The replace
strategy ignores the duplicate record that already
exists. If there is a conflict it prefers the record being loaded.
This preference specifies that all data is kept when cloning a record.
Remember that cloning a record is very simple and powerful way to create new records with the same fields but you have to delete the existing values before entering new ones which is very simple.
The default is false which says to keep the field values when cloning.
Set this preference if you want to avoid deleting the fields manually.
This determines whether a record can be created with no fields.
If it is true, then a new record must have a least one field defined.
The default is false which means that records can be created with no fields so that records.
This preference defines whether or not the user can change a field name on a per record basis.
Setting this preference is not recommended because the presence of
the name
input can be confusing for users, a better approach is
to simply add a new field to the default fields in the preference
section as described in the Fields section.
This is what it looks likes when it is unchecked (false).
When this is not enabled, the user can only choose record fields from
the Record Fields
section of the preferences. See the Record Fields section for more details.
This is what it looks likes when it is checked (true).
The user can replace the default field name (in this case
name
) with whatever they want, perhaps something like full
name
or first name
or last name
. The value
field is where the name is actually entered.
This defines the browser cache strategy for the file password. The
options are none
, prefs
, local
and session
.
The none
option means that the file password is never
stored. The file password is not remembered for the file load
and save operations. Each time you load or save a file you must re-enter
it.
The global
option means that the file password is stored
in a global window session variable. The file password is remembered for
the file load and save operations. It is remembered until the browser
tab is closed.
The local
option means that the file password is stored
in localStorage
. The file password is remembered for the
file load and save operations. It is remembered until it is explicitly
reset.
The session
option means that the file password is
stored in sessionStorage
. The file password is remembered
for the file load and save operations. It is remembered until the
browser tab is closed.
Customized HTML that is added to the about page. It can be used in cases where the field records have been customized to provide an explanation or link to internal documentation.
Its use is described in the About section.
These are the default record fields that are used when creating or editing record fields. They can be can be changed.
See the Fields section for more information about record fields.
At the top of the section there is
icon that is used to create a new record field.
Each default record field has a name, a type (from a pulldown menu)
and a delete button
()
that you click to delete the record field.
The record field names must be unique but you can modify them. They are stored with the each record file individually.
This is what the default records filed preference dialogue looks like.
You must scroll to the bottom of the dialogue and click on
the "Save"
button at the end to save changes. If you do
not, any changes you made will be lost.
PAM, like all web applications, has security challenges. By fully disclosing them here you can understand the challenges and improve your ability to protect your record data.
MITM refers to Monster In The Middle
attacks or, historically,
Man In The Middle
attacks. It an attack where a hostile
eavesdropper inserts themselves in the communications stream between a
client and a server to capture or alter the communications for nefarious
purposes like stealing credentials.
PAM is not susceptible to this attack because it does not communicate with a server. That is because it is a single page web application that is downloaded and run within your browser. All data is local. Nothing is ever transferred over the internet for an eavesdropper to capture.
Third party web site security can be a major source of cybersecurity vulnerabilities because clients cannot know how well such cybersecurity vulnerabilities are mitigated unless that site publishes a detailed report, on a periodic basis, of how often they were attacked successfully and how many attacks they have successfully fended off.
Sadly, most companies do not provide that information. If you are using a password manager or any other service that uses a server, you might want to consider asking them how vulnerable they are to cyberattacks. At a minimum, you will want to understand what is done to protect your data from insider attacks where an employee steals the data.
Sometimes you can get information about the security of a site by looking at Common Vulnerability and Exposures (CVE) reports. See https://www.cve.org/ for more information.
Poor reporting of third party web site cybersecurity vulnerabilities and exposures was one thing that motivated me to write PAM.
Because PAM does not send the data to a server, it is not vulnerable to how cybersecurity is managed on the server by a third party.
You can verify that PAM is not sending data out by monitoring outbound traffic from your system. PAM never sends any outbound data.
PAM encryption and decryption operations are provided by and run inside the secure context of the browser. This is the same secure context used for accessing sites securely for transactions, like your bank. In practice this means that you must access PAM from an HTTPS site.
The safety and security of secure context operations is taken very seriously by the internet standards organization and the organizations that develop the major browsers.
You can read more about secure contexts here and in Reason 6: Secure Context Encryption.
Although it is not an attack vector per se, site reliability is another consideration when choosing a web application because a distributed denial of service (DDoS) attack on the site or a power failure at the site could make it unusable.
Fortunately, most modern web applications are built using commercial cloud software as a service (SaaS) and infrastructure as a service (IaaS) products from vendors like AWS, Azure and GCP so they tend to be very reliable but it is still something to be aware of because if the site or the gateway to the site goes down so does the web application.
PAM, is hosted and served from github.io which also appears to be very reliable but if you are concerned, you can host it wherever you like. Also PAM does not do any backend server communication (as mentioned earlier) so it will like continue to run even if the site goes down temporarily because, once it is loaded, it will stay resident until you close the browser tab.
Another thing to consider is where you store your PAM record file(s). I use iCloud which is also quite reliable and allows access to iCloud files directly from my computers, mobile devices and tablets.
Just make sure that whichever infrastructure as a service (IaaS) offering you choose it is reliable as well because you don’t want to lose access to your file because the IaaS service is not available.
Of course you could simply load and save the data to a local file but that might restrict access to it from other devices (like mobile phones or tables) and you would have to be very diligent about keeping it backed up.
The user enters the record data in decrypted form, so it may be vulnerable to over the shoulder surfing attacks where someone or something (like a camera) watches or films the user typing or opening a record and then clicking or tapping on a password field to display the password in plaintext which could allow that information to be stolen.
This vulnerability can be mitigated by being aware of your surroundings to make sure you are not being watched or filmed.
This is different and easier to mitigate than
key-logging and screen recordingas discussed in the next subsection.
If malware that takes screenshots or does key logging has been installed on your computer, phone or tablet, you are in trouble for a variety of reasons. It means that an attacker can see what you are doing and capture what you are typing.
The best way to mitigate these forms of attacks is to keep your system up to date by installing security patches and by using some sort of security tool or tools to protect your system or, at the very least, recognize the infection.
Yet another type of vulnerability is the clipboard attack
if/when data is copied to the clipboard for cut and paste operations.
This vulnerability exists because the clipboard is a global resource
that can be accessed by other, independent applications.
Clipboard attacks can be mitigated by making sure that your computer does not have malware installed or by not copying to the clipboard. Although it is probably impractical to not use the clipboard at all so, if you do use the clipboard, make sure that you always reset it after any copy/paste operation to minimize any chances that it will be captured by malware or observed by an attacker. You can reset it by simply selection a single letter or word and copying it.
Another, perhaps better, way to mitigate the clipboard vulnerability might be to eliminate the need for the clipboard by modifying PAM to automatically login in for you based on record data using an HTTP POST operation but that is not currently available.
Note that I say might here, because I do not know how secure POST operations are.
If you leave the browser unattended without locking your screen after you have loaded your record data, someone can sit down and see the records because they are impersonating you after you have logged in.
The best way to mitigate this attack is to always lock your screen when you leave the computer unattended.
Web site spoofing could be used to direct you to a website that could be used to steal your information using a look alike web application.
To mitigate that make sure that you accessing the PAM from a known, trusted site.
If you are concerned about this, you can always download, build and run PAM from your own trusted site.
In general a brute force attack is any attack that uses trial and error to crack passwords.
A dictionary attack is a brute force password attack that tries every password in a dictionary to break decrypt sensitive data.
Both attacks are very effective in cases where the attacker has the ability to try many passwords without being locked out and where the password is short.
PAM is vulnerable to dictionary attacks and brute force atttacks because it can be run locally where the attacker can setup an automatic system to try to decrypt the file using the set of available passwords.
Sites that require passwords for authentication can mitigate this type of attack by limiting the number of login attempts allowed.
PAM can also mitigate these types of attacks but it cannot do so automatically because the attacker has access to the source code. Instead you can mitigate these attacks by using strong (high entropy) passwords.
To give you some feel for just how effective this approach is, consider a simple example where we have a password composed of say 20 pseudo-random upper case letters (26), lower case letters (26), digits (10) and 2 special characters.
Thus for 20 characters, there are 6420 or 1,329,227,995,784,915,872,903,807,060,280,344,576 (~1.3 undecillion) possible passwords which is which is one heck of a lot possibilities!
If an attacker were to try to crack such a password using a super powerful computer that could perform 1 billion tests per second (close to the limit of todays technology), it would take something on the order of about a sextillion (1021) years to crack which means that your data is pretty safe if you use such a password.
On the other hand if you use a simple, six character password like
it would take about about a minute so don’t
do that.secret
Ideas for generating strong password are discussed in the next section.
In summary, security can never be fully guaranteed, the best way to protect your data is to follow commonly recommended security practices:
A1/jeans/chosen/since/tuition?!!
(do NOT use this
specific password!).Several folks have asked me why Multi-Factor Authentication (MFA) was not included in PAM to provide and additional layer of security.
In general the MFA approach assumes that the users identity must be checked and validated (authentication) so that the site offering the services knows that it is dealing with the valid user not an impersonator which is a great thing but it is not necessary for PAM because PAM has no site.
Instead PAM is a single page web application with no backend processing, which, once it is loaded, makes it more like a local word processor that is tailored to managing customized records in local files so any additional communication over the internet represents a risk as does storing any user information. Everything is done inside the browser in a secure context.
No outbound information is ever sent to the internet unless the user
specifically requests it via the "Load File"
and
"Save File"
operations while using cloud storage but at
that point all data is encrypted both at the file level and as the HTTPS
transport level which is required for the browser secure context which,
in turn, is required by PAM to function which is pretty safe if
you protect your data with a strong password.
You can verify that PAM is functioning securely by monitoring outbound internet traffic. You should never see any outbound traffic from PAM that is not related to the file load and save operations.
For all of the above reasons, I felt the MFA would not improve security and, hence, was not needed.
The examples in this section talk about how to use this app under different scenarios.
This is the most common usage. It is where personal account records are stored so that you have a permanent, encrypted record of all of your passwords.
To create a file with a single record follow these steps:
"New Record"
option from the menu in the
upper right hand corner.Google email.
url,
loginand
passwordand set their values.
Save Filefrom the menu.
"mystuff.pam"
or "joe.pam"
if your name is
Joeor
"account.pam"
.
".pam"
file extension. If that is the case use the ".txt"
file
extension. Everything loves that and the data is guaranteed to be ASCII
text (even when encrypted).At this point your data is stored. You can add as many additional records as you want or change existing records. As long as you save them, they will be available to you.
To use the data to log into a site.
urllink so that the site opens up in a different tab.
To edit an existing record.
To delete an existing record.
This is a really powerful operation that allows you to quickly create records with the same fields.
To clone a record.
If you want to disable the copying of field data turn off the
Clone Field Values when Cloning Records
preference. That avoids
having to delete each old field value before typing in the new field
value.
This scenario assumes that a small group of trusted people wants to share a common file of account records with credentials that can only be decrypted using a single shared password that is only known to the group.
This might be suitable for a small group that requires administrative access to a small number of accounts.
Because it involves sharing a password, this approach may be too insecure for some.
If this approach is adopted, it would be wise to change the shared password frequently, to audit all access to the shared file as well as audit all access to the accounts. Also, since the shared file must be on a mounted volume that can be seen by the input file dialogue, access to the mount and, by extension, to the file can also be restricted.
Here are the high level steps necessary to share a PAM file.
login
, password
, note
and
host
by editing the preferences and removing the other
fields since all of the records have a specific, known format.Another approach is to create the encrypted PAM file and store it on a publicly accessible web site. Users can then use option #3 in Load File dialogue to load it.
This is a bit of contrived example because you could easily keep all of your recipes with your other personal account data but it might be useful if you want to keep them separated.
The key notion here is the idea of creating two new fields in the
preference dialogue: ingredients
and instructions
, and
then use them when you enter recipes.
Here are the high level steps necessary to get the fields defined.
"Record Fields"
in the preferences section.
"ingredients"
of type textarea.
"instructions"
of type textarea.
To search by an ingredient, set the Search Record Field Values
preference to true by clicking or tapping on it and then saving it.
This is another somewhat of contrived example because you could easily keep all of your book reviews with your other personal account data but it might be useful if you want to keep them separated.
For my book reviews, I enter the book title as the record title and added the following fields using the methodology described in the recipes section above.
Note that I only add records for books that have been read.
name | type | description |
---|---|---|
author | textarea | there maybe multiple authors |
date-read | text | when it was read |
thoughts | textarea | my thoughts about the book |
To search by author, set the Search Record Field Values
preference to true by clicking or tapping on it and then saving it.
These are things that developers might be interested in.
It was built using pure javascript and relies on the browser secure context to provide encryption and decryption.
It uses bootstrap-5 to make it work better in mobile browsers.
It uses pylenium to test the web app which means the github actions file main.yml is pretty interesting because it demonstrates to how to build a complete web test environment using python on an Ubuntu:20.04 VM with a local web server.
Not only that but I wrote my own little, lightweight javascript library to provide a limited functional interface to make coding HTML DOM constructs easier. See the www/js/lib.js source code module.
PAM is free and open-source (FOSS) software that licensed under the MIT Licensing terms.
Although not required, I would appreciate attribution if you decide to copy and use the source code.
Here are the steps to build PAM.
git clone https://github.com/jlinoff/pam.git
make
or make init
www/js/version.js
file and the
help.make run
I could not automate this process because I used a web service.
Downloadbutton was clicked.
pam/www
pam/www/index.html
.pam/www/index.html
to make them relative by prepending a dot to the href
path)
like this.<link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="./favicon-16x16.png">
<link rel="manifest" href="./site.webmanifest">
pam/www/site.webmanifest
to
make them relative as well by prepending a dot to the src
path like this. Note that the original was not not formatted, I
formatted here to make it easier to read."name": "",
"short_name": "",
"icons": [
{
"src": "./android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "./android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}
Here are the steps to test PAM.
make test
The test infrastructure uses python and pylenium to automate user interactions.
Note that PAM will not work unless it is released to a secure (HTTPS) server because it requires a secure context.
Note that installing it on local server (localhost or 127.0.0.1) is considered secure which is convenient for personal use.
Here are the steps.
VERSION
file using semantic versioning.make
to propagate the new version and update
README.md
make web
to create pam-www.tar
which
contains the app in pam/www
.pam-www.tar
on your site.This pre-supposes that you have cloned the pam project from github.
This is one of the several times that I have written a password manager from scratch over the past twenty years and it is intended to be the last. Because this version while it is far from perfect, is good enough for my needs and should provide a decent start for someone who wants to improve it.
If you are interested in the evolution of this project read on.
Below are three previous implementations that are still around followed by a brief chronology of how things progressed over the years.
Circa | 2010 |
Project | https://joelinoff.com/blog/?page_id=1025 |
Webapp | https://projects.joelinoff.com/passman/passman-v0.7/ |
This is the oldest surviving effort. It is an early incarnation written in pure javascript that uses a table paradigm for presenting the data. The UI and the implementation are quite complex.
Circa | 2018 |
Project | https://github.com/eSentire/qspm |
Webapp | https://esentire.github.io/qspm/ |
This is the older effort that was implemented using Rust and javascript and was funded by my employer at that time (eSentire, Inc.) for a hack week project. The UI and the implementation are quite complex.
The acronym stands for Quantum Safe Password Manager. An ambitious name to say the least.
Circa | 2020 |
Project | https://github.com/jlinoff/myvault |
Webapp | https://jlinoff.github.io/myvault |
Help | https://jlinoff.github.io/myvault/help |
This is the precursor to pam. It was implemented using Rust and javascript. I used it for a several of years.
It has poor implementations of the record create and edit dialogues and a poor implementation of the password generator dialogue.
Other than that it was okay.
Circa | 2022 |
Project | https://github.com/jlinoff/pam |
Webapp | https://jlinoff.github.io/pam/www/ |
Help | https://jlinoff.github.io/pam/www/help/ |
This is the latest incarnation and it is pure javascript. It fixes some of the problems seen in the earlier attempts and it leverages bootstrap-5 to make it work better in mobile browsers. The implementation is a bit simpler but like all of the other attempts there is still plenty of room for improvement.
The acronym stands for Personal Accounts Manager or Password Manager or whatever. It doesn’t really matter. I just wanted something short and easy to remember.
I first wrote a password manager in the early 2000’s in javascript. In those days I had to write my own uncertified implementations of the encryption algorithms like AES-256-CBC and AES-256-GCM and DES3 but that was perfectly okay because, back then, my day job involved a lot of security stuff like designing hardware and software (in C++) to implement certified algorithms.
As time went on, I would continue to re-implement password managers as a hobby to learn new skills and refresh old ones. That pretty quickly got me into javascript, python, docker, golang and, a few years ago, to rust. It has been a fun journey and I learned a great deal.
By the time, I got around to writing PAM, I was using the prototype for a lot more than password management (mostly because I could enter records from my phone). It was a useful idiom for record management in general which is where things are today.
You will see that I dropped Rust in the latest incarnation but that is not because I don’t think Rust is suitable or wonderful. Rust is most definitely suitable and wonderful. I dropped it because I did not need it. The secure context had everything I needed.
In a perfect world, I would have done this in emacs
org-mode
(yes, I am one of those) but I was never able to
get remote access from multiple devices working as well as I liked so I
stuck with javascript.
I sincerely hope that there is something here that others can learn from this.
I have really enjoyed playing around with password management over the years. The journey has been great fun.
Enjoy.