Content authorization with Varnish

I’ve been asked about this so many times that I thought I should just post it here. It’s actually very simple to do using restarts.

The problem: you need to check if a user is authorized for an object (which may or may not already be cached by Varnish) by means of an external application.

The solution: the following VCL will pass GET requests from the users to the authorization app. You can modify the URLs, e.g. insert a custom query string if required by the app.

The request is then either denied (if the auth app returns anything other than a 200) or restarted and served from the real backend or from cache.

This is only an example; you can extend it to cache authorization responses, add a control header if you use restarts anywhere else in your VCL, etc.

sub vcl_recv {
        if (req.url ~ "^/authorized_content") {
          if (req.restarts == 0) {
            set req.backend = authorization_backend;
          } else {
            set req.backend = real_backend;
            set req.url = regsub(req.url, "_authorize_me", "");

sub vcl_fetch {
        if (req.url ~ "^/authorized_content" && req.restarts == 0) {
          if (beresp.status == 200) {
          } else {
            error 403 "Not authorized";
This entry was posted in IT and tagged . Bookmark the permalink.

4 Responses to Content authorization with Varnish

  1. asq says:

    fajne/smart. we’ve been doing this with esi so far, but this one require way less effort from webapp. if i understand this correctly it should remove authorized_content prefix in line 8 and not _authorize_me.

    • tgr says:

      Thanks. Actually, it removes _authorize_me intentionally in the example; the idea was to ask for e.g. /authorized_content/foobar.flv_authorize_me, process the authorization and then request /authorized_content/foobar.flv from the real backend. Obviously this is just a silly example. :-)

  2. Radha says:

    Thank u

  3. Michael says:

    Thanks. Works great.

Comments are closed.