Since CUDA supports double precision, and OptiX programs are build on CUDA, you can do double precision math in an OptiX program. You can also pass doubles in a ray payload or in buffers, and use those values in your intersection programs.
What you don’t have direct control over is the ‘t’ values stored by OptiX via rtPotentialIntersection(). Doubles are truncated to floats there, and cannot easily be preserved as doubles. This could cause issues if you have two surfaces that are extremely close in space; close enough so that they overlap in single float32 precision.
OptiX also stores and traverses acceleration structures using float precision. You can partly get around this by padding your bounding boxes, but the ray parameters inside of traversal will be single float.