GRANT SELECT ON SEQUENCE succeeds, but to no effect?
The manual:


  The view role_usage_grants identifies USAGE privileges granted on various kinds of objects where the grantor or grantee is a currently enabled role.


Nothing additional will show up there after GRANT SELECT .... Try instead:

GRANT USAGE ON SEQUENCE public.some_id_sequence TO new_role;


.. if that's, indeed, what you want. The SELECT privilege has limited use for a SEQUENCE, it allows currval() and lastval().
Typically, you want the USAGE privilege which also allows the crucial nextval() in addition to the above. To work with a serial column, for instance. See:


Explicitly granting permissions to update the sequence for a serial column necessary?


So why do you see this confusing line in your test after granting SELECT?


live@live ~ =&gt; select * from information_schema.role_usage_grants limit 1;
┌──────────┬──────────┬────────────────┬───────────────┬──────────────┬─────────────┬────────────────┬──────────────┐
│ grantor  │ grantee  │ object_catalog │ object_schema │  object_name │ object_type │ privilege_type │ is_grantable │
├──────────┼──────────┼────────────────┼───────────────┼──────────────┼─────────────┼────────────────┼──────────────┤
│ old_role │ old_role │ old_role       │ public        │ some_id_seq  │ SEQUENCE    │ USAGE          │ YES          │
└──────────┴──────────┴────────────────┴───────────────┴──────────────┴─────────────┴────────────────┴──────────────┘



The owner of an object has all privileges on it automatically. Hence pg_class.relacl starts out as NULL - signifying default privileges. Once that owner grants privileges to another role, his own privilege is entered explicitly in addition - thus popping up in the information schema views as well. Or, quoting the source:


  If the “Access privileges” column is empty for a given object, it
  means the object has default privileges (that is, its privileges
  column is null). Default privileges always include all privileges for
  the owner, and can include some privileges for PUBLIC depending on the
  object type, as explained above. The first GRANT or REVOKE on an
  object will instantiate the default privileges (producing, for
  example, {miriam=arwdDxt/miriam}) and then modify them per the
  specified request.


Generally, to debug non-trivial stuff, I'd rather look at pg_catalog tables, which are the primary source of truth. pg_class.relacl in this particular case:

SELECT relnamespace::regnamespace, relname, relacl
FROM   pg_class
WHERE  relname = 'some_id_sequence';


Or \z (short for \dp) in psql:

\z some_id_sequence


Assuming old_role is the owner, you should see:

{old_role=rwU/old_role,new_role=r/old_role}  -- after GRANT SELECT...
{old_role=rwU/old_role,new_role=U/old_role}  -- after GRANT USAGE ...
{old_role=rwU/old_role,new_role=rU/old_role}  -- after granting both

And NULL (empty in psql) before granting anything.

Your added output shows that new_role actually has the SELECT privilege, you have just been looking up the wrong view. Seems like new_role is lacking privileges on the public schema - which are normally given to PUBLIC by default.



Aside:  IDENTITY columns in Postgres 11 or later avoid the fuss. Those use sequences just as well, internally, but implicitly owned by the IDENTITY column and with the appropriate privileges automatically. Then you need no separate grants for sequences. See:


Auto increment table column