Skip to main content
Barish Namazov

Optional Security Model

In a recent inquiry from a student in the Software Design class, we discussed an interesting concern — how to restrict users from performing certain actions on a website during specific hours by redirecting them to a logout page. This prompted a thoughtful consideration of a pragmatic security model (separate from student's concern).

When dealing with time-sensitive features in software development, particularly managing different time zones, things get pretty tricky quickly. However, let's put all that timezones problem away and just focus on preventing the users to do some actions when some condition is met.

To effectively implement the "forbidden times" rule for all users, it's essential to address both frontend and backend aspects. The frontend ensures users are aware of action restrictions for usability, while the backend enforces these restrictions, even against potential malicious attempts. One straightforward approach involves logging out users attempting actions during forbidden times, accompanied by a clear notification. Navigation guards on the frontend handle the subsequent redirection, providing a seamless user experience. If you are not aware of what navigation guards are — they basically act as a "middleware" that runs before the user is navigate the page (often used to redirect the user to a login page if they are not logged in).

Why would we want to do this? Let's say I make a small website that allows my dormmates to enter a short message that will be displayed on and spoken out loud by the TV in the common room. We don't really want to trigger the sound at 3 AM when people are sleeping, so by implementing the logic above, we make sure everyone is sleeping nicely.

Moving beyond the "forbidden times" concept, let's explore an alternative perspective—the "focus times." In a hypothetical social media application, users can define focus periods during which they're automatically logged out (with override capabilities for urgent situations). While the technical distinction may seem minor, the conceptual divergence is significant: one emphasizes security, while the other prioritizes productivity.

Do we need to strictly enforce the focus times? No, we don't. A frontend-centric implementation suffices, allowing users to interact with the API outside these focus periods without significantly compromising the feature's intent. I'm sure no one will wake up and think "Oh no, I can't login because this is my focus time! Let me just figure out how to send an API request using my phone to see the number of likes my last post got!".

I like to call this the "optional security model", since adding the security does not help with the purpose of this feature. In fact, to implement it, we can use a very generic Notebook concept I like to use in my apps:

concept Notebook[Item, Context, Content]
  purpose: Keep track of notes for items, each having a context
  OP: After a note in mentioned context is added to the item,
      that note can be accessed later.
  state:
    notes: set Note
    item: Note -> one Item
    content: Note -> one Content
    context: Note -> lone Context
  actions:
    // getByItem, getByContext, getByItemAndContext, 
    // addNote, removeNote, etc.

We can instantiate this Notebook concept for our focus times feature:

include Notebook[User.User, None, TimeRange] as FocusTimes

User.User type comes from the User concept. This basically means that in the notebook, we a note of type TimeRange (which you can easily define as a pair of dates) for each user. The None context means that the note is not associated with any context (context is useful when you want to differentiate between multiple notes for the same item, but in this case that's not needed).

In conclusion, by recognizing this (non-)security model to align with the intended feature purpose, we achieve a pragmatic and efficient implementation, enhancing user experience without unnecessary complexity in our backend.