Hiding Deep in the Woods

Reader Privacy and Evergreen

Galen Charlton / Equinox Software, Inc.

Constant vigilence

My defense is perfect


The best we can do is get better

Why do this?

... it's the law!

... professional ethics

... reducing identity theft risks

... providing education by example

Handling patron data

For every bit of patron data, we should know

  • Why we're storing it all
  • How long we're keeping it
  • Why we're retaining it
  • Who gets to see it
  • Who gets to control access to it
  • Who gets to control its longevity

Don't collect what you don't need

Collecting patron SSNs?


Collecting driver license numbers?

  • There are other ways to verify residency
  • ... and even if you use DL# as a way to check residency... do you really need to hang onto them?

Use HTTPS across the board

Improve your HTTPS settings

  • Disable outdated and insecure protocols and ciphers

Useful tools

  • SSLLabs


  • Outdated clients

Tunnel unencrypted protocols such as SIP2


client = yes
accept =
connect = old_dog_new_tricks.evergreencatalog.com:6443


  • Requires cooperation by SIP2 clients

Control direct access to the database


hostssl    evergreen  circreports  md5
hostnossl  evergreen  circreports  reject

There's more to it than hostssl

  • sslmode=verify-ca
  • sslmode=verify-full
  • Client certificate authentication

Restricted users

CREATE USER circreports ENCRYPTED PASSWORD 'a_good_pw';
GRANT USAGE ON SCHEMA action TO circreports;
GRANT SELECT ON action.circulation TO circreports;

Restricted views

CREATE OR REPLACE VIEW extend_reporter.current_loan_demographics AS
SELECT xact_start,
       pgt.name AS patron_profile,
       acpl.name AS shelving_location
FROM action.circulation circ
JOIN actor.usr au ON (circ.usr = au.id)
JOIN permission.grp_tree pgt ON (au.profile = pgt.id)
JOIN asset.copy acp ON (acp.id = circ.target_copy)
JOIN asset.copy_location acpl ON (acpl.id = acp.location);

GRANT USAGE ON SCHEMA extend_reporter TO circreports;
GRANT SELECT ON extend_reporter.current_loan_demographics circreports;

Restrict access by IP address

  • External firewall
  • iptables / lfw / ufw and friends
  • pg_hba.conf
  • Apache configuration
  • Net::Server (i.e., SIPServer and marc_stream_importer.pl)

Eschew shared logins

  • Not sharing logins is a way of meaning it when you say that patron data is available only to authorized staff.

Regularly purge and anonymize data

... from the filesystem

  • reporter output
  • notices

... from database

  • Age circulations
  • actor.usr_delete() / actor.usr_purge_date()

Evergreen can't do it all by itself

  • Network security
  • Staying on top of patches
  • Staff training


Galen Charlton
Equinox Software, Inc.