Incrementing pointer to pointer by one byte 
If you find an implementation where the size of a pointer to pointer variable contains only 8 bits, (i.e. one that uses 1 byte addressing, btw, very unlikely),  then it will be doable, and only then would it be safe to do so.  Otherwise it would not be considered a practical or safe thing to do.  
For an implementation that uses 64 bit addressing, 64 bits are needed to represent each natural pointer location.  Note however though _[t]he smallest incremental change is [available as a by-product of] the alignment needs of the referenced type. For performance, this often matches the width of the ref type, yet systems can allow less._ (per @Chux in comments) but de-referencing these locations could, and likely would lead to undefined behavior.
And in this statement
 char **cp = (char **)pp; //where pp is defined as int **
the cast, although allowing a compile without complaining, is simply masking a problem.  With the exception of void *, pointer variables are created using the same base type of the object they are to point to for the reason that the sizeof different types can be different, so the pointers designed to point to a particular type can represent its locations accurately.
It is also important to note the following:
            sizeof char ** == sizeof char * == sizeof char *** !!= sizeof char`   
     32bit  4 bytes           4 bytes            4 bytes             1 byte 
     64bit  8 bytes           8 bytes            8 bytes             1 byte  
            sizeof int ** == sizeof int * == sizeof int *** !!= sizeof int`   
     32bit  4 bytes           4 bytes            4 bytes             4 bytes (typically)
     64bit  8 bytes           8 bytes            8 bytes             4 bytes (typically) 
So, unlike the type of a pointer, its size has little to do with it's ability to point to a location containing an object that is smaller, or even larger in size than the pointer used to point to it.  
The purpose of a pointer ( eg char * ) is to store an address to an object of the same base type, in this case char.  If targeting 32bit addressing, then the size of the pointer indicates it can point to 4,294,967,296 different locations (or if 64 bits to 18,446,744,073,709,551,616 locations.) and because in this case it is designed to point to char, each address differs by one byte.
But this really has nothing to do with your observation that when you increment a pointer to pointer to char that you see 8 bytes, and not 1 byte.  It simply has to do with the fact that pointers, in 64bit addressing, require 8 bytes of space, thus the successive printf statements below will always show an increment of 8 bytes between the 1st and 2nd calls:
 char **cp = (char **)pp; 
 size_t size = sizeof(cp);
 printf("address of cp before increment: %p\n", cp);
 cp++;                    // This still moves 8 bytes
 printf("address of cp after increment: %p\n", cp);
 return 0;