How to grant access to a specific table across all databases in Mysql? I want to Grant access like so:
&gt; GRANT INSERT, UPDATE ON `%`.my_table TO 'user'@'%';
ERROR 1146 (42S02): Table '%.my_table' doesn't exist

This is not possible per Mysql documentation on grant:

The _ and % wildcards are permitted when specifying database names in
GRANT statements that grant privileges at the database level

And nothing is mentioned for table level access.
I found similar questions on stackexchange, but they have different use cases. There is Mysql Bug from 2017 that seems to suggest a fix for this specific use case:

Accept statements which have a wildcard in the database name and a
fixed table name.

Is there a workaround?
You will have to script it in a stored procedure.
here is such a script
CREATE DATABASE IF NOT EXISTS grantor;
USE grantor
DELIMITER $$
DROP PROCEDURE IF EXISTS grant_table $$
CREATE PROCEDURE grant_table
(
    tb VARCHAR(64)
   ,userhost VARCHAR(128)
   ,grantlist VARCHAR(255)
)
BEGIN
    DROP TABLE IF EXISTS DBLIST;
    CREATE TABLE DBLIST
    (
        id INT NOT NULL AUTO_INCREMENT,
        db VARCHAR(64),
        PRIMARY KEY (id)
    ) ENGINE=MEMORY;
    INSERT INTO DBLIST (db)
    SELECT table_schema FROM information_schema.tables WHERE
    table_schema NOT IN
    ('information_schema','performance_schema','mysql','sys')
    AND table_name = tb;
    SELECT MAX(id) INTO @rcount FROM DBLIST;
    SELECT @rcount;
    SET @x = 0;
    WHILE @x &lt; @rcount DO
        SET @x = @x + 1;
        SELECT CONCAT('GRANT ',grantlist,' ON `',db,'`.',tb,' TO ',userhost)
        INTO @sql
        FROM DBLIST WHERE id = @x;
        SELECT @sql;
        PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
    END WHILE;    

END $$
DELIMITER ;

Here is a sample call
CREATE TABLE tryout.thistable (id INT NOT NULL PRIMARY KEY,name VARCHAR(20));
CREATE TABLE DMP492.thistable LIKE tryout.thistable;
CREATE TABLE DMP551.thistable LIKE tryout.thistable;
CREATE TABLE DMP579.thistable LIKE tryout.thistable;
CREATE TABLE DMP756.thistable LIKE tryout.thistable;
CALL grantor.grant_table('thistable','ptqd@''%''','INSERT,SELECT');

Here was a sample test I did
MySQL://localhost/root/mysqld.sock/grantor&gt; CREATE DATABASE IF NOT EXISTS grantor;
Query OK, 1 row affected, 1 warning (0.00 sec)

MySQL://localhost/root/mysqld.sock/grantor&gt; USE grantor
Database changed
MySQL://localhost/root/mysqld.sock/grantor&gt; DELIMITER $$
MySQL://localhost/root/mysqld.sock/grantor&gt; DROP PROCEDURE IF EXISTS grant_table $$
Query OK, 0 rows affected (0.00 sec)

MySQL://localhost/root/mysqld.sock/grantor&gt; CREATE PROCEDURE grant_table
    -&gt; (
    -&gt;     tb VARCHAR(64)
    -&gt;    ,userhost VARCHAR(128)
    -&gt;    ,grantlist VARCHAR(255)
    -&gt; )
    -&gt; BEGIN
    -&gt;     DROP TABLE IF EXISTS DBLIST;
    -&gt;     CREATE TABLE DBLIST
    -&gt;     (
    -&gt;         id INT NOT NULL AUTO_INCREMENT,
    -&gt;         db VARCHAR(64),
    -&gt;         PRIMARY KEY (id)
    -&gt;     ) ENGINE=MEMORY;
    -&gt;     INSERT INTO DBLIST (db)
    -&gt;     SELECT table_schema FROM information_schema.tables WHERE
    -&gt;     table_schema NOT IN
    -&gt;     ('information_schema','performance_schema','mysql','sys')
    -&gt;     AND table_name = tb;
    -&gt;     SELECT MAX(id) INTO @rcount FROM DBLIST;
    -&gt;     SELECT @rcount;
    -&gt;     SET @x = 0;
    -&gt;     WHILE @x &lt; @rcount DO
    -&gt;         SET @x = @x + 1;
    -&gt;         SELECT CONCAT('GRANT ',grantlist,' ON `',db,'`.',tb,' TO ',userhost)
    -&gt;         INTO @sql
    -&gt;         FROM DBLIST WHERE id = @x;
    -&gt;         SELECT @sql;
    -&gt;         PREPARE s FROM @sql; EXECUTE s; DEALLOCATE PREPARE s;
    -&gt;     END WHILE;
    -&gt;
    -&gt; END $$
Query OK, 0 rows affected (0.00 sec)

MySQL://localhost/root/mysqld.sock/grantor&gt; DELIMITER ;
MySQL://localhost/root/mysqld.sock/grantor&gt; CALL grantor.grant_table('thistable','ptqd@''%''','INSERT,SELECT');
+---------+
| @rcount |
+---------+
|       5 |
+---------+
1 row in set (0.01 sec)

+-------------------------------------------------------+
| @sql                                                  |
+-------------------------------------------------------+
| GRANT INSERT,SELECT ON `DMP492`.thistable TO ptqd@'%' |
+-------------------------------------------------------+
1 row in set (0.02 sec)

+-------------------------------------------------------+
| @sql                                                  |
+-------------------------------------------------------+
| GRANT INSERT,SELECT ON `DMP551`.thistable TO ptqd@'%' |
+-------------------------------------------------------+
1 row in set (0.02 sec)

+-------------------------------------------------------+
| @sql                                                  |
+-------------------------------------------------------+
| GRANT INSERT,SELECT ON `DMP579`.thistable TO ptqd@'%' |
+-------------------------------------------------------+
1 row in set (0.03 sec)

+-------------------------------------------------------+
| @sql                                                  |
+-------------------------------------------------------+
| GRANT INSERT,SELECT ON `DMP756`.thistable TO ptqd@'%' |
+-------------------------------------------------------+
1 row in set (0.03 sec)

+-------------------------------------------------------+
| @sql                                                  |
+-------------------------------------------------------+
| GRANT INSERT,SELECT ON `tryout`.thistable TO ptqd@'%' |
+-------------------------------------------------------+
1 row in set (0.03 sec)

Query OK, 0 rows affected (0.03 sec)

MySQL://localhost/root/mysqld.sock/grantor&gt; show grants for ptqd@'%';
+------------------------------------------------------------+
| Grants for ptqd@%                                          |
+------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'ptqd'@'%'                           |
| GRANT SELECT, INSERT ON `DMP492`.`thistable` TO 'ptqd'@'%' |
| GRANT SELECT, INSERT ON `tryout`.`thistable` TO 'ptqd'@'%' |
| GRANT SELECT, INSERT ON `DMP756`.`thistable` TO 'ptqd'@'%' |
| GRANT SELECT, INSERT ON `DMP551`.`thistable` TO 'ptqd'@'%' |
| GRANT SELECT, INSERT ON `DMP579`.`thistable` TO 'ptqd'@'%' |
+------------------------------------------------------------+
6 rows in set (0.00 sec)

MySQL://localhost/root/mysqld.sock/grantor&gt;

GIVE IT A TRY !!!