This page describes an effort to automate the process of watermarking course material with unique identifiers to discourage the unwanted distribution of faculty-created documents by students and others.
In my opinion this is a reasonable measure to counter existing problems with
- Students uploading course material to pirate sites like Course Hero,
- Teaching assistants doing the same, but with official solutions
And, in the context of sharing of course material between instructors, it provides a middle ground between not sharing course material and providing no-holds-barred access.

It's not a panacea for unwanted document distribution, but it's a start. There are other growing issues, like the unauthorized ingestion of faculty IP into LLMs.
Couldn't the University's Central IT Department do this?
Yes they could include this in YorkU's learning management system, eClass, but they've officially refused. It's a disappointing but expected position for them to take. Perhaps some enthusiastic senators could take up the cause centrally.
In the mean time we're deploying it for EECS faculty and staff on our department's servers. Because it's useful.
What does the Watermarking Script do?
It provides a free way for faculty and staff to embed user names, IP addresses, a date and a unique identifier in the PDF to allow us to track down the owner of a file that is released without permission. We have access to a log file inside a web directory that contains copies of all of the identifying information that gets inserted in the PDF. This will allow faculty and staff to verify the authenticity of the file when it is found in the wild.
Is this the final version?
No. This is the current, 2025/26 version. It's worked well so far, but it could be made better. I'm not a computer scientist or software engineer -- I don't have expertise in cybersecurity or anything related to that. This solution isn't impervious to attack. With sufficient effort, I'm sure the watermarking can be bypassed. But I don't believe that most people are that determined, will get bored and move on to the next Instagram or TikTok video. Over time, I expect that we will incorporate suggestions for improvements from our colleagues. Given that there are so many smart people in the department, I'm sure we'll come up with improvements.
Deployment
You can test out the watermarked files at these two web links:
- As an EECS faculty or staff person @ https://www.eecs.yorku.ca/~drsmith/watermarkdemoeecs/, and
- As a regular YorkU community member @ https://www.eecs.yorku.ca/~drsmith/watermarkdemoppy/
If you're interested in trying it out yourself, contact me for the files and follow the instructions below to set up your webpage.
Instructions

You can set up these files within your personal web folder or in an EECS course page. The files are currently held in /eecs/home/drsmith/www/watermarkdemoeecs and watermarkdemoppy
- Log in to an EECS server (like with RemoteLab or regular SSH)
- cd www (change to your web directory) and make a new directory
- for example, call it mydemo
- Demo with PPY @
- located, internally, at /eecs/home/drsmith/www/watermarkdemoppy
- Demo with EECS credentials @
- located, internally, at /eecs/home/drsmith/www/watermarkdemoeecs
- Demo with PPY @
- for example, call it mydemo
- Change the permissions on the new directory: chmod 755 mydemo
- Create a password file in your new folder, mydemo
- cd mydemo
- Follow the instructions for creating the .htaccess file here.
- Example:
- Following the instructions here, create an .htaccess file in that directory and use chmod to set its access characteristics
- cd mydemo
- touch .htaccess
- create a security access file without contents (yet)
- update permissions on the .htaccess file, by either:
- chmod 604 .htaccess
- chmod o+r .htaccess
- Update the contents of the .htaccess file using your favourite text editor
In the next section I show you how to modify that .htaccess file depending on your use case.
Your Password File (.htaccess)
Depending on your use case you'll want to set up your password file to be more restrictive or more permissive. Here are a couple of possibilities. For more, go to the password file page.
For anyone with an EECS account
AuthType Basic
AuthName "Name of Webpage You Are Protecting"
AuthBasicProvider ldap
Require valid-user
For just EECS faculty and staff
AuthType Basic
AuthName "Name of Webpage You Are Protecting"
AuthBasicProvider ldap
Require ldap-group cn=faculty,cn=users,dc=ad,dc=eecs,dc=yorku,dc=ca
Require ldap-group cn=tech,cn=users,dc=ad,dc=eecs,dc=yorku,dc=ca
For a specific set of TAs or Students from EECS
AuthType Basic
AuthName "Name of Webpage You Are Protecting"
AuthBasicProvider ldap
Require user firstTA secondTA thirdTA anotherTA lastTA
For anyone with a PPY (York-wide) account
AuthType PYork
AuthName "Name of Webpage You Are Protecting"
PYorkAppID "EECS App"
Require valid-user
For just a specific set of TAs or Students with a PPY account
AuthType PYork
AuthName "Name of Webpage You Are Protecting"
PYorkAppID "EECS App"
Require valid-user firstStudent secondStudent thirdStudent lastStudent
Content: a course page
A basic HTML page with a download button.
The Download Button
You'll want to include a download button on your webpage for the watermarked file. This is the code you need:
<!-- Download button for a watermarked PDF -->
<form action="cgi-bin/returnWatermarkedPDF.cgi" method="get">
<!-- ---------------------------------------------------------- ------->
<!-- TO-DO: put the name of your PDF in value, below. ------->
<!-- Don't put the .pdf extension ------->
<!-- ---------------------------------------------------------- ------->
<input type="hidden" name="file" value="NameOfYourPDF"> <!-- TO-DO: file name w/o extension -->
<button type="submit">text on the download button</button> <!-- TO-DO : write text here -->
</form>
A Minimalist Webpage with the Button
In your main webpage folder create a file called index.html. You can use
touch index.html
to do so. Then, change permissions on that file with
chmod 644 index.html
Assuming that you now have a file called index.html, you can incorporate the button like this:
<!DOCTYPE html>
<html>
<head><title>Watermark demo page</title></head>
<body>
<h1>This is the watermark demo page.</h1>
<p>This is a protected page.</p>
<!-- Download button for a watermarked PDF -->
<form action="cgi-bin/returnWatermarkedPDF.cgi" method="get">
<!-- ---------------------------------------------------------- ------->
<!-- TO-DO: put the name of your PDF in value, below. ------->
<!-- Don't put the .pdf extension ------->
<!-- ---------------------------------------------------------- ------->
<input type="hidden" name="file" value="NameOfYourPDF"> <!-- TO-DO: file name w/o extension -->
<button type="submit">text on the download button</button> <!-- TO-DO : write text here -->
</form>
<h2>Logout from PPY</h2>
<p>
<a href="https://passportyork.yorku.ca/ppylogin/ppylogout"> Logout of PPY (York) </a>
</p>
<p>Note that documents downloaded from this page are watermarked and contain identifying information of the people who download them. They are for personal use only.</p>
<footer>
<p>© 2025 Instructor Name @ York University</p>
</footer>
</body>
</html>
Create a cgi-bin directory
Set up your cgi-bin directory and the watermarking scripts
- Make a cgi-bin directory with mkdir
- Change permissions on the directory:
- chmod 755 cgi-bin
- Put the following files in cgi-bin:
- watermark.tex
- watermark_margins.sh
- returnWatermarkedPDF.cgi
- you can also put a dummy index.html file in here to prevent snooping.
Create an images directory inside the cgi-bin
Within the cgi-bin directory, create an images directory. You can also opt to put a dummy index.html file in here. This folder will hold a unique, temporarily-generated image file that gets embedded in the PDF. After the script is done, the image gets erased.
Make a folder to place your original PDFs
- From the directory with the .htaccess file, create the originalpdfs directory with mkdir.
- Restrict access to the originalpdfs folder:
- chmod 744 originalpdfs
- Put an index.html file inside the originalpdfs folder to hide its contents
- touch originalpdfs/index.html
- Place a PDF in originalpdfs (assuming it's called samplefile.pdf)
- Default permissions should be fine.
Conclusion and future work
The watermarking scripts have been working throughout the 2025/26 academic year in three different courses, serving up files to both students and TAs. I'm sure that there is different information that can be embedded in the PDFs and that variations for placement of the watermarks across and along the edges of the pages can be worked out. Currently, it works best in portrait mode but a version that works for landscape should be worked out, too. Another option is to incorporate it into LaTeX workflows since it already uses LaTeX to layer on the watermarks.
Setup is a little challenging and tedious. I'm sure that there is a better, smoother way to do this... something for the future.
Lastly, more testing can be conducted against automated watermark removal tools and measures for "salting" the contents as a countermeasure to AI ingestion could be considered.
Acknowledgements
This is only possible because Mr. Jason Keltz created the CGI and LaTeX files for this. I wouldn't be writing this without his amazing help. Over and over, I count my lucky stars that I work in a department with such awesome technical staff. Thank you!

James Andrew Smith is a Professional Engineer and Associate Professor in the Electrical Engineering and Computer Science Department of York University’s Lassonde School, with degrees in Electrical and Mechanical Engineering from the University of Alberta and McGill University. Previously a program director in biomedical engineering, his research background spans robotics, locomotion, human birth, music and engineering education. While on sabbatical in 2018-19 with his wife and kids he lived in Strasbourg, France and he taught at the INSA Strasbourg and Hochschule Karlsruhe and wrote about his personal and professional perspectives. James is a proponent of using social media to advocate for justice, equity, diversity and inclusion as well as evidence-based applications of research in the public sphere. You can find him on Twitter. You can find him on BlueSky. Originally from Québec City, he now lives in Toronto, Canada.
